From: Mark Wielaard Date: Tue, 24 Dec 2013 09:37:58 +0000 (+0100) Subject: libdwfl: Fix memory leak in linux-core-attach. Allow reiterating threads. X-Git-Tag: elfutils-0.158~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05a4412f11e9f48c8a67c48cd2fc71684873bb63;p=thirdparty%2Felfutils.git libdwfl: Fix memory leak in linux-core-attach. Allow reiterating threads. core_next_thread would allocate a new thread_arg each time but never free it. We only need one active thread_arg to keep the state. Free it when there are no more threads. It was also not possible to start walking all threads in the core again. Just reset the note offset at the start. Signed-off-by: Mark Wielaard --- diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 807fc2b1e..3f9c52554 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2013-12-24 Mark Wielaard + + * linux-core-attach.c (core_next_thread): Check whether thread_argp + is NULL. Reset core_arg->thread_note_offset and malloc a thread_arg + in that case. Free thread_arg if there are no more threads. + 2013-12-23 Mark Wielaard * dwfl_segment_report_module.c (dwfl_segment_report_module): Free diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c index f259b2c34..cc11467b2 100644 --- a/libdwfl/linux-core-attach.c +++ b/libdwfl/linux-core-attach.c @@ -106,6 +106,23 @@ core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg, size_t desc_offset; Elf_Data *note_data = core_arg->note_data; size_t offset; + + struct thread_arg *thread_arg; + if (*thread_argp == NULL) + { + core_arg->thread_note_offset = 0; + thread_arg = malloc (sizeof (*thread_arg)); + if (thread_arg == NULL) + { + __libdwfl_seterrno (DWFL_E_NOMEM); + return -1; + } + thread_arg->core_arg = core_arg; + *thread_argp = thread_arg; + } + else + thread_arg = (struct thread_arg *) *thread_argp; + while (offset = core_arg->thread_note_offset, offset < note_data->d_size && (core_arg->thread_note_offset = gelf_getnote (note_data, offset, &nhdr, &name_offset, @@ -138,17 +155,11 @@ core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg, ? be32toh (val32) : le32toh (val32)); pid_t tid = (int32_t) val32; eu_static_assert (sizeof val32 <= sizeof tid); - struct thread_arg *thread_arg = malloc (sizeof (*thread_arg)); - if (thread_arg == NULL) - { - __libdwfl_seterrno (DWFL_E_NOMEM); - return -1; - } - thread_arg->core_arg = core_arg; thread_arg->note_offset = offset; - *thread_argp = thread_arg; return tid; } + + free (thread_arg); return 0; }