This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] 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 <mjw@redhat.com>
---
 libdwfl/ChangeLog           |    6 ++++++
 libdwfl/linux-core-attach.c |   27 +++++++++++++++++++--------
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 0e7f80a..b5502cd 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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
diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
index f259b2c..cc11467 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;
 }
 
-- 
1.7.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]