ev_loop_destroy memory leak

Brian Maher brian at brimworks.com
Tue Dec 28 15:44:03 CET 2010


I've seen "0 bytes lost in ..." messages when you use realloc() to
free() memory (aka call it with the second argument being zero).  In
my case, I solved the problem by writing a realloc() replacement that
checks if the second argument is zero, and if so it calls free()...
similarly if the first argument is NULL my realloc() replacement calls
malloc()... but ultimately this is just a false alarm (perhaps it has
been fixed in newer versions of valgrind?).

Cheers,
-Brian

On Tue, Dec 28, 2010 at 6:35 AM, Juan Pablo L
<jpablolorenzetti at gmail.com> wrote:
> Hi, i m trying to build an application using libev for the first time, this
> application was written with glib but i m trying to change it into libev, i
> have 1 issue and 1 question: the following code gives memory leaks at
> ev_loop_destroy according to valgrind:
>
> #include <unistd.h>
> #include <stdio.h>
> #include <time.h>
> #include <string.h>
> #include <sys/time.h>
> #include <errno.h>
> #include <pthread.h>
> #include <glib.h>
> #include "async_callback.h"
> #include "log.h"
>
> #define EV_STANDALONE 1
> #include <ev.c>
>
> //
> // globals
> //
>
> typedef struct _LogObject
> {
>     FILE *log_file;
>     char *logpath;
>     int logpath_len;
>     int log_handler_id;
>     struct ev_loop *main_loop;
>     ev_async callback_source;
>     //async_source as;
>     GThread *log_thread;
> }LogObject;
>
> typedef struct _LogData
> {
>     char *log_domain;
>     GLogLevelFlags level;
>     char *message;
> }LogData;
>
> static LogObject g_log_object;
>
> // handler for all log messages
> void gfep_log_handler(const char *p_log_domain,GLogLevelFlags p_level,char
> *p_message,void *p_user_data);
>
> // entry thread function
> void log_run(void *p_log_object);
>
> // switch the log file after 3600 segs
> bool log_switch_file(LogObject *p_log_object);
>
> // write into the log file
> bool log_write_file(struct ev_loop *main_loop,ev_async *callback_source,int
> events);
>
> // delete a LogData object passed to the loop
> void log_handler_free_log_data(LogData *p_log_data);
>
> bool init_logging(char *p_logpath)
> {
>     g_log_object.main_loop = ev_loop_new(EVFLAG_AUTO);
>     ev_async_init(&g_log_object.callback_source,(void*)log_write_file);
>     ev_async_start(g_log_object.main_loop,&g_log_object.callback_source);
>     ev_unref(g_log_object.main_loop);
>
>     // create the thread
>     g_log_object.log_thread =
> g_thread_create((GThreadFunc)log_run,&g_log_object,TRUE,&error);
>     if(g_log_object.log_thread == NULL)
>     {
>         printf("Could not start log thread: %s",error->message);
>         g_error_free(error);
>         return false;
>     }
>     g_thread_set_priority(g_log_object.log_thread,G_THREAD_PRIORITY_LOW);
>
>     // start logging
>     g_message("Logging started");
>
>     return true;
> }
>
> void stop_logging()
> {
>     g_message("Logging stopped");
>
>     ev_async_stop(g_log_object.main_loop,&g_log_object.callback_source);
>     ev_break(g_log_object.main_loop,EVBREAK_ALL);
>     ev_loop_destroy(g_log_object.main_loop);
>
>
>     if(g_log_object.log_thread != NULL)
>     {
>         // join the thread
>         g_thread_join(g_log_object.log_thread);
>     }
>
>     // remove the handler
>     g_log_remove_handler(NULL,g_log_object.log_handler_id);
>
>     // free allocated memory
>     g_free(g_log_object.logpath);
>
>     // close the file
>     if(g_log_object.log_file != NULL)
>     {
>         fclose(g_log_object.log_file);
>     }
> }
>
> void gfep_log_handler(const char *p_log_domain,GLogLevelFlags p_level,char
> *p_message,void *p_user_data)
> {
>     log_data->message = strdup(p_message);
>     // send it to the log thread
>     g_log_object.callback_source.data = strdup(p_message);
>     ev_async_send(g_log_object.main_loop,&g_log_object.callback_source);
>
> }
>
> void log_run(void *p_log_object)
> {
>     LogObject *log_object = (LogObject*)p_log_object;
>
>     ev_run(log_object->main_loop,0);
>     g_thread_exit(NULL);
> }
>
> bool log_write_file(struct ev_loop *main_loop,ev_async *callback_source,int
> events)
> {
>     printf("%s\n",/*((LogData*)callback_source->data)->message*/"");
>     return true;
> }
>
> I omitted other things, as you can see the ev_run is running in a separate
> thread, the functions init_logging and and stop_logging are called from the
> main thread to start and stop logging, after this is executed valgrind
> reports the following:
>
> ==13453== 0 bytes in 1 blocks are definitely lost in loss record 5 of 38
> ==13453==    at 0x4005BDC: malloc (vg_replace_malloc.c:195)
> ==13453==    by 0x4005C66: realloc (vg_replace_malloc.c:476)
> ==13453==    by 0x804C0B4: ev_realloc_emul (ev.c:611)
> ==13453==    by 0x804C0DE: ev_realloc (ev.c:637)
> ==13453==    by 0x804ECF8: ev_loop_destroy (ev.c:1832)
> ==13453==    by 0x80534B7: stop_logging (log.c:116)
> ==13453==    by 0xAB9EFE: exit (in /lib/libc-2.12.90.so)
> ==13453==    by 0xAA0E1D: (below main) (in /lib/libc-2.12.90.so)
>
> and also gives 9 errors (which are the 9 memory leaks) even thou it says 0
> bytes was lost. so i have never seen this kind of reports before. Also, i
> would like to know, why if i do not do an ev_unref after statrting the
> watcher i get a segmentation fault when i stop the application ? thanks!!!!
>
> _______________________________________________
> libev mailing list
> libev at lists.schmorp.de
> http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
>



-- 
Brian Maher >> Glory to God <<



More information about the libev mailing list