Re: [libuv] When to free dynamically allocated requests?

177 views
Skip to first unread message

Ben Noordhuis

unread,
Nov 9, 2012, 7:23:29 PM11/9/12
to li...@googlegroups.com
On Sat, Nov 10, 2012 at 12:57 AM, Michael Buhot <m.b...@gmail.com> wrote:
> It is possible to free dynamically allocated requests in the associated
> callback function?
> When I run the code below through valgrind, I see access after free errors -
> does libuv need the handle to not be free'd until after the callback
> returns?
> Apologies if this is documented somewhere already, I could only find
> examples where the request structures are globals.
>
> void free_handle_in_callback(uv_idle_t* idle, int status)
> {
> uv_idle_stop(idle);
> free(idle);
> }
>
> int main(int argc, char** argv)
> {
> uv_loop_t* loop = uv_loop_new();
> uv_idle_t* idle = malloc(sizeof(uv_idle_t));
> uv_idle_init(loop, idle);
> uv_idle_start(idle, free_handle_in_callback);
> uv_run(loop);
> uv_loop_delete(loop);
>
> return 0;
> }
>
> valgrind --tool=memcheck output:
>
> ==2853== Memcheck, a memory error detector
> ==2853== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
> ==2853== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
> ==2853== Command: ./wordcount
> ==2853==
> status is 0
> ==2853== Invalid read of size 8
> ==2853== at 0x406938: uv__run_idle (loop-watcher.c:62)
> ==2853== by 0x4050CE: uv__run (core.c:277)
> ==2853== by 0x405145: uv_run (core.c:287)
> ==2853== by 0x403ADA: main (wordcount.c:124)
> ==2853== Address 0x5912d70 is 80 bytes inside a block of size 88 free'd
> ==2853== at 0x4C2A739: free (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==2853== by 0x406933: uv__run_idle (loop-watcher.c:62)
> ==2853== by 0x4050CE: uv__run (core.c:277)
> ==2853== by 0x405145: uv_run (core.c:287)
> ==2853== by 0x403ADA: main (wordcount.c:124)
> ==2853==
> ==2853== Invalid read of size 4
> ==2853== at 0x40A8A2: uv__signal_loop_cleanup (signal.c:234)
> ==2853== by 0x405EDB: uv__loop_delete (loop.c:85)
> ==2853== by 0x404F6D: uv_loop_delete (core.c:241)
> ==2853== by 0x403AE2: main (wordcount.c:125)
> ==2853== Address 0x5912d38 is 24 bytes inside a block of size 88 free'd
> ==2853== at 0x4C2A739: free (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==2853== by 0x406933: uv__run_idle (loop-watcher.c:62)
> ==2853== by 0x4050CE: uv__run (core.c:277)
> ==2853== by 0x405145: uv_run (core.c:287)
> ==2853== by 0x403ADA: main (wordcount.c:124)
> ==2853==
> ==2853== Invalid read of size 8
> ==2853== at 0x40A8BA: uv__signal_loop_cleanup (signal.c:231)
> ==2853== by 0x405EDB: uv__loop_delete (loop.c:85)
> ==2853== by 0x404F6D: uv_loop_delete (core.c:241)
> ==2853== by 0x403AE2: main (wordcount.c:125)
> ==2853== Address 0x5912d48 is 40 bytes inside a block of size 88 free'd
> ==2853== at 0x4C2A739: free (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==2853== by 0x406933: uv__run_idle (loop-watcher.c:62)
> ==2853== by 0x4050CE: uv__run (core.c:277)
> ==2853== by 0x405145: uv_run (core.c:287)
> ==2853== by 0x403ADA: main (wordcount.c:124)
> ==2853==
> ==2853==
> ==2853== HEAP SUMMARY:
> ==2853== in use at exit: 0 bytes in 0 blocks
> ==2853== total heap usage: 7 allocs, 7 frees, 2,976 bytes allocated
> ==2853==
> ==2853== All heap blocks were freed -- no leaks are possible
> ==2853==
> ==2853== For counts of detected and suppressed errors, rerun with: -v
> ==2853== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)

Free the handle in your close callback, never before.

void close_cb(uv_handle_t* handle)
{
free(handle);
}

void idle_cb(uv_idle_t* handle, int status)
{
uv_close((uv_handle_t*) handle, close_cb);
// or:
uv_close((uv_handle_t*) handle, (uv_close_cb) free);
}
Reply all
Reply to author
Forward
0 new messages