]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Add dwfl_core_file_attach and dwfl_linux_proc_attach.
authorMark Wielaard <mjw@redhat.com>
Mon, 30 Dec 2013 21:00:57 +0000 (22:00 +0100)
committerMark Wielaard <mjw@redhat.com>
Tue, 31 Dec 2013 12:59:51 +0000 (13:59 +0100)
Rewrite __libdwfl_attach_state_for_pid and __libdwfl_attach_state_for_core
as public functions and don't call them from dwfl_linux_proc_report and
dwfl_core_file_report anymore. This lets the user attach state explicitly
independ from how the dwfl modules have been reported. Since attaching
state is an explicit action now the error can be returned directly and we
don't need to keep track of process_attach_error. dwfl_linux_proc_attach
lets the user can tell libdwfl whether caller takes care of ptrace
attaching and stopping the threads under inspection, or whether the
callback needs to take care of that and detaching again.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
17 files changed:
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/argp-std.c
libdwfl/core-file.c
libdwfl/dwfl_begin.c
libdwfl/dwfl_frame.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libdwfl/linux-core-attach.c
libdwfl/linux-pid-attach.c
libdwfl/linux-proc-maps.c
src/ChangeLog
src/stack.c
tests/ChangeLog
tests/backtrace-dwarf.c
tests/backtrace.c

index 2b677595ae9e0c878093f74a868b80729eb56225..6e779c8e3cb7f4fe225872ad29bcbf6fc1f406ab 100644 (file)
@@ -1,3 +1,8 @@
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+       * libdw.map (ELFUTILS_0.158): Add dwfl_core_file_attach and
+       dwfl_linux_proc_attach.
+
 2013-12-20  Mark Wielaard  <mjw@redhat.com>
 
        * libdw.map (ELFUTILS_0.158): Add dwfl_getthread_frames.
index 08c4ddcc424fba18b25e8e2008882fec467a4ca6..d0e4731742ca95952598d3321cf02cf75fe14492 100644 (file)
@@ -288,4 +288,7 @@ ELFUTILS_0.158 {
     dwfl_module_getsymtab_first_global;
     dwfl_module_addrinfo;
     dwfl_module_getsym_info;
+
+    dwfl_core_file_attach;
+    dwfl_linux_proc_attach;
 } ELFUTILS_0.157;
index 6c983b2b4111c1daa3317ad4b3735e0905b51a6d..2190899eed4acf1a7c80a1c761f01a0f0434bd4f 100644 (file)
@@ -1,3 +1,35 @@
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+       * argp-std.c (parse_opt): Call dwfl_linux_proc_attach and
+       dwfl_core_file_attach explicitly.
+       * core-file.c (dwfl_core_file_report): Don't call
+       __libdwfl_attach_state_for_core implicitly.
+       * dwfl_begin.c (dwfl_begin): Remove setting of process_attach_error.
+       * dwfl_frame.c (dwfl_pid): Set errno to DWFL_E_NO_ATTACH_STATE, not
+       process_attach_error.
+       (dwfl_getthreads): Likewise.
+       (getthread): Likewise.
+       * libdwfl.h (dwfl_core_file_report): Update documentation.
+       (dwfl_linux_proc_report): Likewise.
+       (dwfl_core_file_attach): New function declaration.
+       (dwfl_linux_proc_attach): Likewise.
+       * libdwflP.h (struct Dwfl): Remove process_attach_error.
+       (__libdwfl_attach_state_for_pid): Removed declaration.
+       (__libdwfl_attach_state_for_core): Likewise.
+       (dwfl_core_file_attach): New internal declaration.
+       (dwfl_linux_proc_attach): Likewise.
+       (attach_state_for_core): Renamed to...
+       (dwfl_core_file_attach): ...this. Change return type.
+       (__libdwfl_attach_state_for_core): Removed.
+       * linux-pid-attach.c (struct pid_arg): Add assume_ptrace_stopped.
+       (pid_set_initial_registers): Check assume_ptrace_stopped before
+       calling ptrace.
+       (pid_thread_detach): Likewise.
+       (__libdwfl_attach_state_for_pid): Renamed to...
+       (dwfl_linux_proc_attach): ...this. Adjust return type.
+       * linux-proc-maps.c (dwfl_linux_proc_report): Don't call
+       __libdwfl_attach_state_for_pid implicitly.
+
 2013-12-28  Mark Wielaard  <mjw@redhat.com>
 
        * linux-proc-maps.c (dwfl_linux_proc_find_elf): Don't return special
index cf178eee4a379c574e4672ff8e9a69aecc793372..3a2d2a59ef112317e04ca0959934f1d5441c5beb 100644 (file)
@@ -170,6 +170,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
            int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
            if (result != 0)
              return fail (dwfl, result, arg);
+
+           result = INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
+           if (result != 0)
+             /* Non-fatal to not be able to attach to process.  */
+             failure (dwfl, result, _("cannot attach to process"));
            opt->dwfl = dwfl;
          }
        else
@@ -296,6 +301,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
                return fail (dwfl, result, opt->core);
              }
 
+           result = INTUSE(dwfl_core_file_attach) (dwfl, core);
+           if (result < 0)
+             /* Non-fatal to not be able to attach to core.  */
+             failure (dwfl, result, _("cannot attach to core"));
+
            /* From now we leak FD and CORE.  */
 
            if (result == 0)
index 92745bd68b223e217836fc1c73ae238112a45a8f..4ce63c4e64c837bbcf2023aec6819801d31d540a 100644 (file)
@@ -559,13 +559,6 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
 
   clear_r_debug_info (&r_debug_info);
 
-  if (listed > 0)
-    {
-      /* Possible error is ignored, DWFL still may be useful for non-unwinding
-        operations.  */
-      __libdwfl_attach_state_for_core (dwfl, elf);
-    }
-
   /* We return the number of modules we found if we found any.
      If we found none, we return -1 instead of 0 if there was an
      error rather than just nothing found.  */
index 490da90549167720f5ab589f8726007210d6963a..44c16a9212b8b971f9c2e119116bbae5540eb4a3 100644 (file)
@@ -44,7 +44,6 @@ dwfl_begin (const Dwfl_Callbacks *callbacks)
     {
       dwfl->callbacks = callbacks;
       dwfl->offline_next_address = OFFLINE_REDZONE;
-      dwfl->process_attach_error = DWFL_E_NO_ATTACH_STATE;
     }
 
   return dwfl;
index 28008e9033a59fbe8c78f6867b9233340f6699b5..e45cf14c888e52e7b96cf465b593388e57387e1c 100644 (file)
@@ -200,7 +200,7 @@ dwfl_pid (Dwfl *dwfl)
 {
   if (dwfl->process == NULL)
     {
-      __libdwfl_seterrno (dwfl->process_attach_error);
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
       return -1;
     }
   return dwfl->process->pid;
@@ -235,7 +235,7 @@ dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
   Dwfl_Process *process = dwfl->process;
   if (process == NULL)
     {
-      __libdwfl_seterrno (dwfl->process_attach_error);
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
       return -1;
     }
 
@@ -306,7 +306,7 @@ getthread (Dwfl *dwfl, pid_t tid,
   Dwfl_Process *process = dwfl->process;
   if (process == NULL)
     {
-      __libdwfl_seterrno (dwfl->process_attach_error);
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
       return -1;
     }
 
index 67785ea3053c086b454ef843ea34301b974c8bc7..2bb4f455af17dc05c125718123eb7655cbfe10b4 100644 (file)
@@ -361,16 +361,13 @@ extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
    supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded
    into the DWFL map.  This might call dwfl_report_elf on file names found in
    the dump if reading some link_map files is the only way to ascertain those
-   modules' addresses.  dwfl_attach_state is also called for DWFL,
-   dwfl_core_file_report does not fail if the dwfl_attach_state call has failed.
-   Returns the number of modules reported, or -1 for errors.  */
+   modules' addresses.  Returns the number of modules reported, or -1 for
+   errors.  */
 extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable);
 
 /* Call dwfl_report_module for each file mapped into the address space of PID.
-   dwfl_attach_state is also called for DWFL, dwfl_linux_proc_report does
-   not fail if the dwfl_attach_state call has failed.
    Returns zero on success, -1 if dwfl_report_module failed,
-   or an errno code if opening the kernel binary failed.  */
+   or an errno code if opening the proc files failed.  */
 extern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid);
 
 /* Similar, but reads an input stream in the format of Linux /proc/PID/maps
@@ -717,6 +714,23 @@ bool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
                        void *dwfl_arg)
   __nonnull_attribute__ (1, 4);
 
+/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
+   thread state from the ELF core file.  Returns the pid number extracted
+   from the core file, or -1 for errors.  */
+extern int dwfl_core_file_attach (Dwfl *dwfl, Elf *elf);
+
+/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
+   thread state from the proc file system.  Uses ptrace to attach and stop
+   the thread under inspection and detaches when thread_detach is called
+   and unwinding for the thread is done, unless ASSUME_PTRACE_STOPPED is
+   true.  If ASSUME_PTRACE_STOPPED is true the caller should make sure that
+   the thread is ptrace attached and stopped before unwinding by calling
+   either dwfl_thread_getframes or dwfl_getthread_frames.  Returns zero on
+   success, -1 if dwfl_attach_state failed, or an errno code if opening the
+   proc files failed.  */
+extern int dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid,
+                                  bool assume_ptrace_stopped);
+
 /* Return PID for the process associated with DWFL.  Function returns -1 if
    dwfl_attach_state was not called for DWFL.  */
 pid_t dwfl_pid (Dwfl *dwfl)
index 63615a8a586e91b7f23e487b3c80f6ad1ece11b9..710e69923c94e6e382edceaabd488cf0ac3a7640 100644 (file)
@@ -108,7 +108,6 @@ struct Dwfl
   Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
 
   Dwfl_Process *process;
-  Dwfl_Error process_attach_error;
 
   GElf_Addr offline_next_address;
 
@@ -531,14 +530,6 @@ extern void __libdwfl_process_free (Dwfl_Process *process)
 extern void __libdwfl_frame_unwind (Dwfl_Frame *state)
   internal_function;
 
-/* Call dwfl_attach_state for PID, return true if successful.  */
-extern bool __libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
-  internal_function;
-
-/* Call dwfl_attach_state for CORE, return true if successful.  */
-extern bool __libdwfl_attach_state_for_core (Dwfl *dwfl, Elf *core)
-  internal_function;
-
 /* Align segment START downwards or END upwards addresses according to DWFL.  */
 extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
   internal_function;
@@ -657,6 +648,7 @@ INTDECL (dwfl_addrmodule)
 INTDECL (dwfl_addrsegment)
 INTDECL (dwfl_addrdwarf)
 INTDECL (dwfl_addrdie)
+INTDECL (dwfl_core_file_attach)
 INTDECL (dwfl_core_file_report)
 INTDECL (dwfl_getmodules)
 INTDECL (dwfl_module_addrdie)
@@ -685,6 +677,7 @@ INTDECL (dwfl_standard_find_debuginfo)
 INTDECL (dwfl_link_map_report)
 INTDECL (dwfl_linux_kernel_find_elf)
 INTDECL (dwfl_linux_kernel_module_section_address)
+INTDECL (dwfl_linux_proc_attach)
 INTDECL (dwfl_linux_proc_report)
 INTDECL (dwfl_linux_proc_maps_report)
 INTDECL (dwfl_linux_proc_find_elf)
index cc11467b2cae024a936d1f04df8e1a2fd228866c..1002788e11e50e633c876d4ebe0e65a69da8439a 100644 (file)
@@ -306,30 +306,36 @@ static const Dwfl_Thread_Callbacks core_thread_callbacks =
   NULL, /* core_thread_detach */
 };
 
-static Dwfl_Error
-attach_state_for_core (Dwfl *dwfl, Elf *core)
+int
+dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
 {
   Ebl *ebl = ebl_openbackend (core);
   if (ebl == NULL)
-    return DWFL_E_LIBEBL;
+    {
+      __libdwfl_seterrno (DWFL_E_LIBEBL);
+      return -1;
+    }
   size_t nregs = ebl_frame_nregs (ebl);
   if (nregs == 0)
     {
+      __libdwfl_seterrno (DWFL_E_NO_UNWIND);
       ebl_closebackend (ebl);
-      return DWFL_E_NO_UNWIND;
+      return -1;
     }
   GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem);
   if (ehdr == NULL)
     {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
       ebl_closebackend (ebl);
-      return DWFL_E_LIBELF;
+      return -1;
     }
   assert (ehdr->e_type == ET_CORE);
   size_t phnum;
   if (elf_getphdrnum (core, &phnum) < 0)
     {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
       ebl_closebackend (ebl);
-      return DWFL_E_LIBELF;
+      return -1;
     }
   pid_t pid = -1;
   Elf_Data *note_data = NULL;
@@ -388,14 +394,16 @@ attach_state_for_core (Dwfl *dwfl, Elf *core)
   if (pid == -1)
     {
       /* No valid NT_PRPSINFO recognized in this CORE.  */
+      __libdwfl_seterrno (DWFL_E_BADELF);
       ebl_closebackend (ebl);
-      return DWFL_E_BADELF;
+      return -1;
     }
   struct core_arg *core_arg = malloc (sizeof *core_arg);
   if (core_arg == NULL)
     {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
       ebl_closebackend (ebl);
-      return DWFL_E_NOMEM;
+      return -1;
     }
   core_arg->core = core;
   core_arg->note_data = note_data;
@@ -404,31 +412,10 @@ attach_state_for_core (Dwfl *dwfl, Elf *core)
   if (! INTUSE(dwfl_attach_state) (dwfl, core, pid, &core_thread_callbacks,
                                   core_arg))
     {
-      Dwfl_Error error = dwfl_errno ();
-      assert (error != DWFL_E_NOERROR);
       free (core_arg);
       ebl_closebackend (ebl);
-      return error;
-    }
-  return DWFL_E_NOERROR;
-}
-
-bool
-internal_function
-__libdwfl_attach_state_for_core (Dwfl *dwfl, Elf *core)
-{
-  if (dwfl->process != NULL)
-    {
-      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
-      return false;
+      return -1;
     }
-  Dwfl_Error error = attach_state_for_core (dwfl, core);
-  assert ((dwfl->process != NULL) == (error == DWFL_E_NOERROR));
-  dwfl->process_attach_error = error;
-  if (error != DWFL_E_NOERROR)
-    {
-      __libdwfl_seterrno (error);
-      return false;
-    }
-  return true;
+  return pid;
 }
+INTDEF (dwfl_core_file_attach)
index 70bd666af30d69692fb2f866a496017f32f84f98..21ff4b99ec1a7b155c8480827c497b9860dcfb95 100644 (file)
@@ -44,6 +44,8 @@ struct pid_arg
   pid_t tid_attached;
   /* Valid only if TID_ATTACHED is not zero.  */
   bool tid_was_stopped;
+  /* True if threads are ptrace stopped by caller.  */
+  bool assume_ptrace_stopped;
 };
 
 static bool
@@ -239,7 +241,8 @@ pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
   struct pid_arg *pid_arg = thread_arg;
   assert (pid_arg->tid_attached == 0);
   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
-  if (! ptrace_attach (tid, &pid_arg->tid_was_stopped))
+  if (! pid_arg->assume_ptrace_stopped
+      && ! ptrace_attach (tid, &pid_arg->tid_was_stopped))
     return false;
   pid_arg->tid_attached = tid;
   Dwfl_Process *process = thread->process;
@@ -263,12 +266,16 @@ pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
   assert (pid_arg->tid_attached == tid);
   pid_arg->tid_attached = 0;
-  /* This handling is needed only on older Linux kernels such as
-     2.6.32-358.23.2.el6.ppc64.  Later kernels such as 3.11.7-200.fc19.x86_64
-     remember the T (stopped) state themselves and no longer need to pass
-     SIGSTOP during PTRACE_DETACH.  */
-  ptrace (PTRACE_DETACH, tid, NULL,
-         (void *) (intptr_t) (pid_arg->tid_was_stopped ? SIGSTOP : 0));
+  if (! pid_arg->assume_ptrace_stopped)
+    {
+      /* This handling is needed only on older Linux kernels such as
+         2.6.32-358.23.2.el6.ppc64.  Later kernels such as
+         3.11.7-200.fc19.x86_64 remember the T (stopped) state
+         themselves and no longer need to pass SIGSTOP during
+         PTRACE_DETACH.  */
+      ptrace (PTRACE_DETACH, tid, NULL,
+             (void *) (intptr_t) (pid_arg->tid_was_stopped ? SIGSTOP : 0));
+    }
 }
 
 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
@@ -281,9 +288,8 @@ static const Dwfl_Thread_Callbacks pid_thread_callbacks =
   pid_thread_detach,
 };
 
-bool
-internal_function
-__libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
+int
+dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
 {
   char buffer[36];
   FILE *procfile;
@@ -293,7 +299,7 @@ __libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
   snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
   procfile = fopen (buffer, "r");
   if (procfile == NULL)
-    return false;
+    return errno;
 
   char *line = NULL;
   size_t linelen = 0;
@@ -307,32 +313,30 @@ __libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
   fclose (procfile);
 
   if (pid == 0)
-    return false;
+    return ESRCH;
 
   char dirname[64];
   int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
   assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
   DIR *dir = opendir (dirname);
   if (dir == NULL)
-    {
-      __libdwfl_seterrno (DWFL_E_ERRNO);
-      return false;
-    }
+    return errno;
   struct pid_arg *pid_arg = malloc (sizeof *pid_arg);
   if (pid_arg == NULL)
     {
       closedir (dir);
-      __libdwfl_seterrno (DWFL_E_NOMEM);
-      return false;
+      return ENOMEM;
     }
   pid_arg->dir = dir;
   pid_arg->tid_attached = 0;
+  pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
   if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
                                   pid_arg))
     {
       closedir (dir);
       free (pid_arg);
-      return false;
+      return -1;
     }
-  return true;
+  return 0;
 }
+INTDEF (dwfl_linux_proc_attach)
index b1f8b331ab93be12859fd1805db848f606540806..cdb6959db38210fdec7a62498a810f66d03f001c 100644 (file)
@@ -301,13 +301,6 @@ dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
 
   fclose (f);
 
-  if (result == 0)
-    {
-      /* Possible error is ignored, DWFL still may be useful for non-unwinding
-        operations.  */
-      __libdwfl_attach_state_for_pid (dwfl, pid);
-    }
-
   return result;
 }
 INTDEF (dwfl_linux_proc_report)
index cb9c8151bd49472a631e5e2ab37e07f736bbbb73..811004d34b941a4f269a09277106eb8646fb7eff 100644 (file)
@@ -1,3 +1,8 @@
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+       * stack.c (parse_opt): Explicitly call dwfl_linux_proc_attach
+       or dwfl_core_file_attach and check for errors.
+
 2013-12-28  Mark Wielaard  <mjw@redhat.com>
 
        * stack.c (print_frames): Remove address width code and use...
index 156455c05408eadb1df5d126482266d6baa993ef..2c1d8ff734ab38f5bbf267cc72d72c28fc4eaf97 100644 (file)
@@ -443,6 +443,22 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
       if (dwfl_report_end (dwfl, NULL, NULL) != 0)
        error (EXIT_BAD, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
 
+      if (pid != 0)
+       {
+         int err = dwfl_linux_proc_attach (dwfl, pid, false);
+         if (err < 0)
+           error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %d: %s", pid,
+                  dwfl_errmsg (-1));
+         else if (err > 0)
+           error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %d", pid);
+       }
+
+      if (core != NULL)
+       {
+         if (dwfl_core_file_attach (dwfl, core) < 0)
+           error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1));
+       }
+
       /* Makes sure we are properly attached.  */
       if (dwfl_pid (dwfl) < 0)
        error (EXIT_BAD, 0, "dwfl_pid: %s\n", dwfl_errmsg (-1));
index 23c5051dab2a0dee420b958079ae23483539b589..5c80e9bf593a0a4ff304fcc1b9b4885f8a245421 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+       * backtrace-dwarf.c (report_pid): Explicitly call
+       dwfl_linux_proc_attach and check for errors.
+       * backtrace.c (report_pid): Likewise.
+
 2013-12-21  Mark Wielaard  <mjw@redhat.com>
 
        * backtrace.c (callback_verify): Only assert that case 5 is the last
index aa12315a5ed24eb72554dc3ee8e87cbba0d2b9d2..3a3e76328e0c3dc74212ada98ec13e259d2ba00b 100644 (file)
@@ -41,6 +41,12 @@ report_pid (Dwfl *dwfl, pid_t pid)
 
   if (dwfl_report_end (dwfl, NULL, NULL) != 0)
     error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  result = dwfl_linux_proc_attach (dwfl, pid, false);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_attach");
 }
 
 static Dwfl *
index 8a7d6dfcb1d0dd5f063a22f040ba26c200eee20c..64f90c43318a6482d718555cb78625e1e4520a0c 100644 (file)
@@ -279,6 +279,12 @@ report_pid (Dwfl *dwfl, pid_t pid)
 
   if (dwfl_report_end (dwfl, NULL, NULL) != 0)
     error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  result = dwfl_linux_proc_attach (dwfl, pid, false);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_attach");
 }
 
 static Dwfl *