Mark Wielaard 1648a11
commit 68b1afa36d2389c4f2fb526d0b134e5a3c68dedb
Mark Wielaard 1648a11
Author: Mark Wielaard <mjw@redhat.com>
Mark Wielaard 1648a11
Date:   Tue Jun 10 15:09:23 2014 +0200
Mark Wielaard 1648a11
Mark Wielaard 1648a11
    libdwfl: dwfl_standard_argp should not fail when not able to attach Dwfl.
Mark Wielaard 1648a11
    
Mark Wielaard 1648a11
    As pointed out in https://bugzilla.redhat.com/show_bug.cgi?id=1107654
Mark Wielaard 1648a11
    commit 191080 introduced a thinko that caused dwfl_standard_argp
Mark Wielaard 1648a11
    to fail if the Dwfl couldn't be attached. Instead of generating a warning
Mark Wielaard 1648a11
    as the comment intended, the failure would be fatal. But even warning
Mark Wielaard 1648a11
    about dwfl_core_file_attach () or dwfl_linux_proc_attach () failing
Mark Wielaard 1648a11
    would be a mistake. The caller/user might not be interested in such
Mark Wielaard 1648a11
    a non-fatal issue. So just ignore if the call failed for whatever reason.
Mark Wielaard 1648a11
    If the caller is interested in warning up front about this issue, then
Mark Wielaard 1648a11
    dwfl_pid () should be called to check the Dwfl is attached. Things should
Mark Wielaard 1648a11
    work just fine for anything that doesn't call any of the dwfl_state related
Mark Wielaard 1648a11
    functions.
Mark Wielaard 1648a11
    
Mark Wielaard 1648a11
    Signed-off-by: Mark Wielaard <mjw@redhat.com>
Mark Wielaard 1648a11
Mark Wielaard 1648a11
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
Mark Wielaard 1648a11
index 8d2bc6a..42b7e78 100644
Mark Wielaard 1648a11
--- a/libdwfl/argp-std.c
Mark Wielaard 1648a11
+++ b/libdwfl/argp-std.c
Mark Wielaard 1648a11
@@ -171,10 +171,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
Mark Wielaard 1648a11
 	    if (result != 0)
Mark Wielaard 1648a11
 	      return fail (dwfl, result, arg);
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
-	    result = INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
Mark Wielaard 1648a11
-	    if (result != 0)
Mark Wielaard 1648a11
-	      /* Non-fatal to not be able to attach to process.  */
Mark Wielaard 1648a11
-	      failure (dwfl, result, _("cannot attach to process"));
Mark Wielaard 1648a11
+	    /* Non-fatal to not be able to attach to process, ignore error.  */
Mark Wielaard 1648a11
+	    INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
 	    opt->dwfl = dwfl;
Mark Wielaard 1648a11
 	  }
Mark Wielaard 1648a11
 	else
Mark Wielaard 1648a11
@@ -301,10 +300,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
Mark Wielaard 1648a11
 		return fail (dwfl, result, opt->core);
Mark Wielaard 1648a11
 	      }
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
-	    result = INTUSE(dwfl_core_file_attach) (dwfl, core);
Mark Wielaard 1648a11
-	    if (result < 0)
Mark Wielaard 1648a11
-	      /* Non-fatal to not be able to attach to core.  */
Mark Wielaard 1648a11
-	      failure (dwfl, result, _("cannot attach to core"));
Mark Wielaard 1648a11
+	    /* Non-fatal to not be able to attach to core, ignore error.  */
Mark Wielaard 1648a11
+	    INTUSE(dwfl_core_file_attach) (dwfl, core);
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
 	    /* From now we leak FD and CORE.  */
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
commit 14beac3b6f22b8d7a054980f74c4f8d33b969fc4
Mark Wielaard 1648a11
Author: Mark Wielaard <mjw@redhat.com>
Mark Wielaard 1648a11
Date:   Wed Jun 11 15:14:23 2014 +0200
Mark Wielaard 1648a11
Mark Wielaard 1648a11
    libdwfl: Record dwfl_attach_state error and return it on failure.
Mark Wielaard 1648a11
    
Mark Wielaard 1648a11
    When dwfl_attach_state fails functions that need the process state should
Mark Wielaard 1648a11
    return the error that caused the attach to fail. Use this in the backtrace
Mark Wielaard 1648a11
    test to signal any attach failure. This makes sure that architectures that
Mark Wielaard 1648a11
    don't provide unwinder support get properly detected (and the tests SKIPs)
Mark Wielaard 1648a11
    Also don't assert when trying to attach a non-core ELF file, but return an
Mark Wielaard 1648a11
    error to indicate failure.
Mark Wielaard 1648a11
    
Mark Wielaard 1648a11
    Signed-off-by: Mark Wielaard <mjw@redhat.com>
Mark Wielaard 1648a11
Mark Wielaard 1648a11
diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c
Mark Wielaard 1648a11
index fd0b9ae..f6f86c0 100644
Mark Wielaard 1648a11
--- a/libdwfl/dwfl_frame.c
Mark Wielaard 1648a11
+++ b/libdwfl/dwfl_frame.c
Mark Wielaard 1648a11
@@ -117,6 +117,7 @@ __libdwfl_process_free (Dwfl_Process *process)
Mark Wielaard 1648a11
   if (process->ebl_close)
Mark Wielaard 1648a11
     ebl_closebackend (process->ebl);
Mark Wielaard 1648a11
   free (process);
Mark Wielaard 1648a11
+  dwfl->attacherr = DWFL_E_NOERROR;
Mark Wielaard 1648a11
 }
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
 /* Allocate new Dwfl_Process for DWFL.  */
Mark Wielaard 1648a11
@@ -134,17 +135,24 @@ bool
Mark Wielaard 1648a11
 dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
Mark Wielaard 1648a11
 		   const Dwfl_Thread_Callbacks *thread_callbacks, void *arg)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
-  if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
Mark Wielaard 1648a11
-      || thread_callbacks->set_initial_registers == NULL)
Mark Wielaard 1648a11
+  if (dwfl->process != NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
Mark Wielaard 1648a11
+      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
Mark Wielaard 1648a11
       return false;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
-  if (dwfl->process != NULL)
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
+  /* Reset any previous error, we are just going to try again.  */
Mark Wielaard 1648a11
+  dwfl->attacherr = DWFL_E_NOERROR;
Mark Wielaard 1648a11
+  if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
Mark Wielaard 1648a11
+      || thread_callbacks->set_initial_registers == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
Mark Wielaard 1648a11
+      dwfl->attacherr = DWFL_E_INVALID_ARGUMENT;
Mark Wielaard 1648a11
+    fail:
Mark Wielaard 1648a11
+      dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr);
Mark Wielaard 1648a11
+      __libdwfl_seterrno (dwfl->attacherr);
Mark Wielaard 1648a11
       return false;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
   Ebl *ebl;
Mark Wielaard 1648a11
   bool ebl_close;
Mark Wielaard 1648a11
   if (elf != NULL)
Mark Wielaard 1648a11
@@ -180,8 +188,8 @@ dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
Mark Wielaard 1648a11
   if (ebl == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
       /* Not identified EBL from any of the modules.  */
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_PROCESS_NO_ARCH);
Mark Wielaard 1648a11
-      return false;
Mark Wielaard 1648a11
+      dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   process_alloc (dwfl);
Mark Wielaard 1648a11
   Dwfl_Process *process = dwfl->process;
Mark Wielaard 1648a11
@@ -189,8 +197,8 @@ dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
       if (ebl_close)
Mark Wielaard 1648a11
 	ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_NOMEM);
Mark Wielaard 1648a11
-      return false;
Mark Wielaard 1648a11
+      dwfl->attacherr = DWFL_E_NOMEM;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   process->ebl = ebl;
Mark Wielaard 1648a11
   process->ebl_close = ebl_close;
Mark Wielaard 1648a11
@@ -204,6 +212,12 @@ INTDEF(dwfl_attach_state)
Mark Wielaard 1648a11
 pid_t
Mark Wielaard 1648a11
 dwfl_pid (Dwfl *dwfl)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
+  if (dwfl->attacherr != DWFL_E_NOERROR)
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      __libdwfl_seterrno (dwfl->attacherr);
Mark Wielaard 1648a11
+      return -1;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
   if (dwfl->process == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
       __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
Mark Wielaard 1648a11
@@ -238,6 +252,12 @@ int
Mark Wielaard 1648a11
 dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
Mark Wielaard 1648a11
 		 void *arg)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
+  if (dwfl->attacherr != DWFL_E_NOERROR)
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      __libdwfl_seterrno (dwfl->attacherr);
Mark Wielaard 1648a11
+      return -1;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
   Dwfl_Process *process = dwfl->process;
Mark Wielaard 1648a11
   if (process == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
@@ -309,6 +329,12 @@ getthread (Dwfl *dwfl, pid_t tid,
Mark Wielaard 1648a11
 	   int (*callback) (Dwfl_Thread *thread, void *arg),
Mark Wielaard 1648a11
 	   void *arg)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
+  if (dwfl->attacherr != DWFL_E_NOERROR)
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      __libdwfl_seterrno (dwfl->attacherr);
Mark Wielaard 1648a11
+      return -1;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
+
Mark Wielaard 1648a11
   Dwfl_Process *process = dwfl->process;
Mark Wielaard 1648a11
   if (process == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
Mark Wielaard 1648a11
index 9b03d8a..30c0f8a 100644
Mark Wielaard 1648a11
--- a/libdwfl/libdwflP.h
Mark Wielaard 1648a11
+++ b/libdwfl/libdwflP.h
Mark Wielaard 1648a11
@@ -91,7 +91,8 @@ typedef struct Dwfl_Process Dwfl_Process;
Mark Wielaard 1648a11
   DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state"))   \
Mark Wielaard 1648a11
   DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state"))	      \
Mark Wielaard 1648a11
   DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
Mark Wielaard 1648a11
-  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))
Mark Wielaard 1648a11
+  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))			      \
Mark Wielaard 1648a11
+  DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
 #define DWFL_ERROR(name, text) DWFL_E_##name,
Mark Wielaard 1648a11
 typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
Mark Wielaard 1648a11
@@ -110,6 +111,7 @@ struct Dwfl
Mark Wielaard 1648a11
   Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   Dwfl_Process *process;
Mark Wielaard 1648a11
+  Dwfl_Error attacherr;      /* Previous error attaching process.  */
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   GElf_Addr offline_next_address;
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
Mark Wielaard 1648a11
index 1002788..7ef3f25 100644
Mark Wielaard 1648a11
--- a/libdwfl/linux-core-attach.c
Mark Wielaard 1648a11
+++ b/libdwfl/linux-core-attach.c
Mark Wielaard 1648a11
@@ -309,33 +309,41 @@ static const Dwfl_Thread_Callbacks core_thread_callbacks =
Mark Wielaard 1648a11
 int
Mark Wielaard 1648a11
 dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
+  Dwfl_Error err = DWFL_E_NOERROR;
Mark Wielaard 1648a11
   Ebl *ebl = ebl_openbackend (core);
Mark Wielaard 1648a11
   if (ebl == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_LIBEBL);
Mark Wielaard 1648a11
+      err = DWFL_E_LIBEBL;
Mark Wielaard 1648a11
+    fail_err:
Mark Wielaard 1648a11
+      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
Mark Wielaard 1648a11
+	dwfl->attacherr = __libdwfl_canon_error (err);
Mark Wielaard 1648a11
+      __libdwfl_seterrno (err);
Mark Wielaard 1648a11
       return -1;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   size_t nregs = ebl_frame_nregs (ebl);
Mark Wielaard 1648a11
   if (nregs == 0)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_NO_UNWIND);
Mark Wielaard 1648a11
+      err = DWFL_E_NO_UNWIND;
Mark Wielaard 1648a11
+    fail:
Mark Wielaard 1648a11
       ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return -1;
Mark Wielaard 1648a11
+      goto fail_err;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem);
Mark Wielaard 1648a11
   if (ehdr == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_LIBELF);
Mark Wielaard 1648a11
-      ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return -1;
Mark Wielaard 1648a11
+      err = DWFL_E_LIBELF;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
+  if (ehdr->e_type != ET_CORE)
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      err = DWFL_E_NO_CORE_FILE;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
-  assert (ehdr->e_type == ET_CORE);
Mark Wielaard 1648a11
   size_t phnum;
Mark Wielaard 1648a11
   if (elf_getphdrnum (core, &phnum) < 0)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_LIBELF);
Mark Wielaard 1648a11
-      ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return -1;
Mark Wielaard 1648a11
+      err = DWFL_E_LIBELF;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   pid_t pid = -1;
Mark Wielaard 1648a11
   Elf_Data *note_data = NULL;
Mark Wielaard 1648a11
@@ -351,8 +359,8 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   if (note_data == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return DWFL_E_LIBELF;
Mark Wielaard 1648a11
+      err = DWFL_E_LIBELF;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   size_t offset = 0;
Mark Wielaard 1648a11
   GElf_Nhdr nhdr;
Mark Wielaard 1648a11
@@ -394,16 +402,14 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
Mark Wielaard 1648a11
   if (pid == -1)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
       /* No valid NT_PRPSINFO recognized in this CORE.  */
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_BADELF);
Mark Wielaard 1648a11
-      ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return -1;
Mark Wielaard 1648a11
+      err = DWFL_E_BADELF;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   struct core_arg *core_arg = malloc (sizeof *core_arg);
Mark Wielaard 1648a11
   if (core_arg == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
-      __libdwfl_seterrno (DWFL_E_NOMEM);
Mark Wielaard 1648a11
-      ebl_closebackend (ebl);
Mark Wielaard 1648a11
-      return -1;
Mark Wielaard 1648a11
+      err = DWFL_E_NOMEM;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   core_arg->core = core;
Mark Wielaard 1648a11
   core_arg->note_data = note_data;
Mark Wielaard 1648a11
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
Mark Wielaard 1648a11
index 8aee721..d60955e 100644
Mark Wielaard 1648a11
--- a/libdwfl/linux-pid-attach.c
Mark Wielaard 1648a11
+++ b/libdwfl/linux-pid-attach.c
Mark Wielaard 1648a11
@@ -290,13 +290,23 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
Mark Wielaard 1648a11
 {
Mark Wielaard 1648a11
   char buffer[36];
Mark Wielaard 1648a11
   FILE *procfile;
Mark Wielaard 1648a11
+  int err = 0; /* The errno to return and set for dwfl->attcherr.  */
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   /* Make sure to report the actual PID (thread group leader) to
Mark Wielaard 1648a11
      dwfl_attach_state.  */
Mark Wielaard 1648a11
   snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
Mark Wielaard 1648a11
   procfile = fopen (buffer, "r");
Mark Wielaard 1648a11
   if (procfile == NULL)
Mark Wielaard 1648a11
-    return errno;
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      err = errno;
Mark Wielaard 1648a11
+    fail:
Mark Wielaard 1648a11
+      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
Mark Wielaard 1648a11
+	{
Mark Wielaard 1648a11
+	  errno = err;
Mark Wielaard 1648a11
+	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
Mark Wielaard 1648a11
+	}
Mark Wielaard 1648a11
+      return err;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   char *line = NULL;
Mark Wielaard 1648a11
   size_t linelen = 0;
Mark Wielaard 1648a11
@@ -317,19 +327,26 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
Mark Wielaard 1648a11
   fclose (procfile);
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   if (pid == 0)
Mark Wielaard 1648a11
-    return ESRCH;
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      err = ESRCH;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
   char dirname[64];
Mark Wielaard 1648a11
   int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
Mark Wielaard 1648a11
   assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
Mark Wielaard 1648a11
   DIR *dir = opendir (dirname);
Mark Wielaard 1648a11
   if (dir == NULL)
Mark Wielaard 1648a11
-    return errno;
Mark Wielaard 1648a11
+    {
Mark Wielaard 1648a11
+      err = errno;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
+    }
Mark Wielaard 1648a11
   struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
Mark Wielaard 1648a11
   if (pid_arg == NULL)
Mark Wielaard 1648a11
     {
Mark Wielaard 1648a11
       closedir (dir);
Mark Wielaard 1648a11
-      return ENOMEM;
Mark Wielaard 1648a11
+      err = ENOMEM;
Mark Wielaard 1648a11
+      goto fail;
Mark Wielaard 1648a11
     }
Mark Wielaard 1648a11
   pid_arg->dir = dir;
Mark Wielaard 1648a11
   pid_arg->tid_attached = 0;
Mark Wielaard 1648a11
diff --git a/tests/backtrace.c b/tests/backtrace.c
Mark Wielaard 1648a11
index 1a4709b..ce0bd17 100644
Mark Wielaard 1648a11
--- a/tests/backtrace.c
Mark Wielaard 1648a11
+++ b/tests/backtrace.c
Mark Wielaard 1648a11
@@ -1,5 +1,5 @@
Mark Wielaard 1648a11
 /* Test program for unwinding of frames.
Mark Wielaard 1648a11
-   Copyright (C) 2013 Red Hat, Inc.
Mark Wielaard 1648a11
+   Copyright (C) 2013, 2014 Red Hat, Inc.
Mark Wielaard 1648a11
    This file is part of elfutils.
Mark Wielaard 1648a11
 
Mark Wielaard 1648a11
    This file is free software; you can redistribute it and/or modify
Mark Wielaard 1648a11
@@ -459,6 +459,9 @@ main (int argc __attribute__ ((unused)), char **argv)
Mark Wielaard 1648a11
     };
Mark Wielaard 1648a11
   (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
Mark Wielaard 1648a11
   assert (dwfl != NULL);
Mark Wielaard 1648a11
+  /* We want to make sure the dwfl was properly attached.  */
Mark Wielaard 1648a11
+  if (dwfl_pid (dwfl) < 0)
Mark Wielaard 1648a11
+    error (2, 0, "dwfl_pid: %s", dwfl_errmsg (-1));
Mark Wielaard 1648a11
   dump (dwfl);
Mark Wielaard 1648a11
   dwfl_end (dwfl);
Mark Wielaard 1648a11
   return 0;