]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Fix memory leak in linux-core-attach. Allow reiterating threads.
authorMark Wielaard <mjw@redhat.com>
Tue, 24 Dec 2013 09:37:58 +0000 (10:37 +0100)
committerMark Wielaard <mjw@redhat.com>
Tue, 31 Dec 2013 12:58:32 +0000 (13:58 +0100)
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 <mjw@redhat.com>
libdwfl/ChangeLog
libdwfl/linux-core-attach.c

index 807fc2b1e01d612edb02b0fac9e2bee423cdd821..3f9c52554ff6bcbbc35052e46fc7f408face7da0 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-24  Mark Wielaard  <mjw@redhat.com>
+
+       * 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  <mjw@redhat.com>
 
        * dwfl_segment_report_module.c (dwfl_segment_report_module): Free
index f259b2c34c4b35122ca41707b5c24933ba9b5d4f..cc11467b2cae024a936d1f04df8e1a2fd228866c 100644 (file)
@@ -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;
 }