forked from rpms/elfutils
		
	0.159-4 Add elfutils-0.159-argp-attach.patch (#1107654)
This commit is contained in:
		
							parent
							
								
									2e16caff89
								
							
						
					
					
						commit
						1648a11415
					
				
							
								
								
									
										359
									
								
								elfutils-0.159-argp-attach.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								elfutils-0.159-argp-attach.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,359 @@ | ||||
| commit 68b1afa36d2389c4f2fb526d0b134e5a3c68dedb | ||||
| Author: Mark Wielaard <mjw@redhat.com> | ||||
| Date:   Tue Jun 10 15:09:23 2014 +0200 | ||||
| 
 | ||||
|     libdwfl: dwfl_standard_argp should not fail when not able to attach Dwfl. | ||||
|      | ||||
|     As pointed out in https://bugzilla.redhat.com/show_bug.cgi?id=1107654 | ||||
|     commit 191080 introduced a thinko that caused dwfl_standard_argp | ||||
|     to fail if the Dwfl couldn't be attached. Instead of generating a warning | ||||
|     as the comment intended, the failure would be fatal. But even warning | ||||
|     about dwfl_core_file_attach () or dwfl_linux_proc_attach () failing | ||||
|     would be a mistake. The caller/user might not be interested in such | ||||
|     a non-fatal issue. So just ignore if the call failed for whatever reason. | ||||
|     If the caller is interested in warning up front about this issue, then | ||||
|     dwfl_pid () should be called to check the Dwfl is attached. Things should | ||||
|     work just fine for anything that doesn't call any of the dwfl_state related | ||||
|     functions. | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mjw@redhat.com> | ||||
| 
 | ||||
| diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
 | ||||
| index 8d2bc6a..42b7e78 100644
 | ||||
| --- a/libdwfl/argp-std.c
 | ||||
| +++ b/libdwfl/argp-std.c
 | ||||
| @@ -171,10 +171,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
 | ||||
|  	    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"));
 | ||||
| +	    /* Non-fatal to not be able to attach to process, ignore error.  */
 | ||||
| +	    INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
 | ||||
| +
 | ||||
|  	    opt->dwfl = dwfl; | ||||
|  	  } | ||||
|  	else | ||||
| @@ -301,10 +300,8 @@ 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"));
 | ||||
| +	    /* Non-fatal to not be able to attach to core, ignore error.  */
 | ||||
| +	    INTUSE(dwfl_core_file_attach) (dwfl, core);
 | ||||
|   | ||||
|  	    /* From now we leak FD and CORE.  */ | ||||
|   | ||||
| commit 14beac3b6f22b8d7a054980f74c4f8d33b969fc4 | ||||
| Author: Mark Wielaard <mjw@redhat.com> | ||||
| Date:   Wed Jun 11 15:14:23 2014 +0200 | ||||
| 
 | ||||
|     libdwfl: Record dwfl_attach_state error and return it on failure. | ||||
|      | ||||
|     When dwfl_attach_state fails functions that need the process state should | ||||
|     return the error that caused the attach to fail. Use this in the backtrace | ||||
|     test to signal any attach failure. This makes sure that architectures that | ||||
|     don't provide unwinder support get properly detected (and the tests SKIPs) | ||||
|     Also don't assert when trying to attach a non-core ELF file, but return an | ||||
|     error to indicate failure. | ||||
|      | ||||
|     Signed-off-by: Mark Wielaard <mjw@redhat.com> | ||||
| 
 | ||||
| diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c
 | ||||
| index fd0b9ae..f6f86c0 100644
 | ||||
| --- a/libdwfl/dwfl_frame.c
 | ||||
| +++ b/libdwfl/dwfl_frame.c
 | ||||
| @@ -117,6 +117,7 @@ __libdwfl_process_free (Dwfl_Process *process)
 | ||||
|    if (process->ebl_close) | ||||
|      ebl_closebackend (process->ebl); | ||||
|    free (process); | ||||
| +  dwfl->attacherr = DWFL_E_NOERROR;
 | ||||
|  } | ||||
|   | ||||
|  /* Allocate new Dwfl_Process for DWFL.  */ | ||||
| @@ -134,17 +135,24 @@ bool
 | ||||
|  dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid, | ||||
|  		   const Dwfl_Thread_Callbacks *thread_callbacks, void *arg) | ||||
|  { | ||||
| -  if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
 | ||||
| -      || thread_callbacks->set_initial_registers == NULL)
 | ||||
| +  if (dwfl->process != NULL)
 | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
 | ||||
| +      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
 | ||||
|        return false; | ||||
|      } | ||||
| -  if (dwfl->process != NULL)
 | ||||
| +
 | ||||
| +  /* Reset any previous error, we are just going to try again.  */
 | ||||
| +  dwfl->attacherr = DWFL_E_NOERROR;
 | ||||
| +  if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
 | ||||
| +      || thread_callbacks->set_initial_registers == NULL)
 | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
 | ||||
| +      dwfl->attacherr = DWFL_E_INVALID_ARGUMENT;
 | ||||
| +    fail:
 | ||||
| +      dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr);
 | ||||
| +      __libdwfl_seterrno (dwfl->attacherr);
 | ||||
|        return false; | ||||
|      } | ||||
| +
 | ||||
|    Ebl *ebl; | ||||
|    bool ebl_close; | ||||
|    if (elf != NULL) | ||||
| @@ -180,8 +188,8 @@ dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
 | ||||
|    if (ebl == NULL) | ||||
|      { | ||||
|        /* Not identified EBL from any of the modules.  */ | ||||
| -      __libdwfl_seterrno (DWFL_E_PROCESS_NO_ARCH);
 | ||||
| -      return false;
 | ||||
| +      dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    process_alloc (dwfl); | ||||
|    Dwfl_Process *process = dwfl->process; | ||||
| @@ -189,8 +197,8 @@ dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
 | ||||
|      { | ||||
|        if (ebl_close) | ||||
|  	ebl_closebackend (ebl); | ||||
| -      __libdwfl_seterrno (DWFL_E_NOMEM);
 | ||||
| -      return false;
 | ||||
| +      dwfl->attacherr = DWFL_E_NOMEM;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    process->ebl = ebl; | ||||
|    process->ebl_close = ebl_close; | ||||
| @@ -204,6 +212,12 @@ INTDEF(dwfl_attach_state)
 | ||||
|  pid_t | ||||
|  dwfl_pid (Dwfl *dwfl) | ||||
|  { | ||||
| +  if (dwfl->attacherr != DWFL_E_NOERROR)
 | ||||
| +    {
 | ||||
| +      __libdwfl_seterrno (dwfl->attacherr);
 | ||||
| +      return -1;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    if (dwfl->process == NULL) | ||||
|      { | ||||
|        __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE); | ||||
| @@ -238,6 +252,12 @@ int
 | ||||
|  dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg), | ||||
|  		 void *arg) | ||||
|  { | ||||
| +  if (dwfl->attacherr != DWFL_E_NOERROR)
 | ||||
| +    {
 | ||||
| +      __libdwfl_seterrno (dwfl->attacherr);
 | ||||
| +      return -1;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    Dwfl_Process *process = dwfl->process; | ||||
|    if (process == NULL) | ||||
|      { | ||||
| @@ -309,6 +329,12 @@ getthread (Dwfl *dwfl, pid_t tid,
 | ||||
|  	   int (*callback) (Dwfl_Thread *thread, void *arg), | ||||
|  	   void *arg) | ||||
|  { | ||||
| +  if (dwfl->attacherr != DWFL_E_NOERROR)
 | ||||
| +    {
 | ||||
| +      __libdwfl_seterrno (dwfl->attacherr);
 | ||||
| +      return -1;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    Dwfl_Process *process = dwfl->process; | ||||
|    if (process == NULL) | ||||
|      { | ||||
| diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
 | ||||
| index 9b03d8a..30c0f8a 100644
 | ||||
| --- a/libdwfl/libdwflP.h
 | ||||
| +++ b/libdwfl/libdwflP.h
 | ||||
| @@ -91,7 +91,8 @@ typedef struct Dwfl_Process Dwfl_Process;
 | ||||
|    DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state"))   \ | ||||
|    DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state"))	      \ | ||||
|    DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \ | ||||
| -  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))
 | ||||
| +  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))			      \
 | ||||
| +  DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
 | ||||
|   | ||||
|  #define DWFL_ERROR(name, text) DWFL_E_##name, | ||||
|  typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error; | ||||
| @@ -110,6 +111,7 @@ struct Dwfl
 | ||||
|    Dwfl_Module *modulelist;    /* List in order used by full traversals.  */ | ||||
|   | ||||
|    Dwfl_Process *process; | ||||
| +  Dwfl_Error attacherr;      /* Previous error attaching process.  */
 | ||||
|   | ||||
|    GElf_Addr offline_next_address; | ||||
|   | ||||
| diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
 | ||||
| index 1002788..7ef3f25 100644
 | ||||
| --- a/libdwfl/linux-core-attach.c
 | ||||
| +++ b/libdwfl/linux-core-attach.c
 | ||||
| @@ -309,33 +309,41 @@ static const Dwfl_Thread_Callbacks core_thread_callbacks =
 | ||||
|  int | ||||
|  dwfl_core_file_attach (Dwfl *dwfl, Elf *core) | ||||
|  { | ||||
| +  Dwfl_Error err = DWFL_E_NOERROR;
 | ||||
|    Ebl *ebl = ebl_openbackend (core); | ||||
|    if (ebl == NULL) | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_LIBEBL);
 | ||||
| +      err = DWFL_E_LIBEBL;
 | ||||
| +    fail_err:
 | ||||
| +      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
 | ||||
| +	dwfl->attacherr = __libdwfl_canon_error (err);
 | ||||
| +      __libdwfl_seterrno (err);
 | ||||
|        return -1; | ||||
|      } | ||||
|    size_t nregs = ebl_frame_nregs (ebl); | ||||
|    if (nregs == 0) | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_NO_UNWIND);
 | ||||
| +      err = DWFL_E_NO_UNWIND;
 | ||||
| +    fail:
 | ||||
|        ebl_closebackend (ebl); | ||||
| -      return -1;
 | ||||
| +      goto fail_err;
 | ||||
|      } | ||||
|    GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem); | ||||
|    if (ehdr == NULL) | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_LIBELF);
 | ||||
| -      ebl_closebackend (ebl);
 | ||||
| -      return -1;
 | ||||
| +      err = DWFL_E_LIBELF;
 | ||||
| +      goto fail;
 | ||||
| +    }
 | ||||
| +  if (ehdr->e_type != ET_CORE)
 | ||||
| +    {
 | ||||
| +      err = DWFL_E_NO_CORE_FILE;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
| -  assert (ehdr->e_type == ET_CORE);
 | ||||
|    size_t phnum; | ||||
|    if (elf_getphdrnum (core, &phnum) < 0) | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_LIBELF);
 | ||||
| -      ebl_closebackend (ebl);
 | ||||
| -      return -1;
 | ||||
| +      err = DWFL_E_LIBELF;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    pid_t pid = -1; | ||||
|    Elf_Data *note_data = NULL; | ||||
| @@ -351,8 +359,8 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
 | ||||
|      } | ||||
|    if (note_data == NULL) | ||||
|      { | ||||
| -      ebl_closebackend (ebl);
 | ||||
| -      return DWFL_E_LIBELF;
 | ||||
| +      err = DWFL_E_LIBELF;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    size_t offset = 0; | ||||
|    GElf_Nhdr nhdr; | ||||
| @@ -394,16 +402,14 @@ dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
 | ||||
|    if (pid == -1) | ||||
|      { | ||||
|        /* No valid NT_PRPSINFO recognized in this CORE.  */ | ||||
| -      __libdwfl_seterrno (DWFL_E_BADELF);
 | ||||
| -      ebl_closebackend (ebl);
 | ||||
| -      return -1;
 | ||||
| +      err = DWFL_E_BADELF;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    struct core_arg *core_arg = malloc (sizeof *core_arg); | ||||
|    if (core_arg == NULL) | ||||
|      { | ||||
| -      __libdwfl_seterrno (DWFL_E_NOMEM);
 | ||||
| -      ebl_closebackend (ebl);
 | ||||
| -      return -1;
 | ||||
| +      err = DWFL_E_NOMEM;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    core_arg->core = core; | ||||
|    core_arg->note_data = note_data; | ||||
| diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
 | ||||
| index 8aee721..d60955e 100644
 | ||||
| --- a/libdwfl/linux-pid-attach.c
 | ||||
| +++ b/libdwfl/linux-pid-attach.c
 | ||||
| @@ -290,13 +290,23 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
 | ||||
|  { | ||||
|    char buffer[36]; | ||||
|    FILE *procfile; | ||||
| +  int err = 0; /* The errno to return and set for dwfl->attcherr.  */
 | ||||
|   | ||||
|    /* Make sure to report the actual PID (thread group leader) to | ||||
|       dwfl_attach_state.  */ | ||||
|    snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid); | ||||
|    procfile = fopen (buffer, "r"); | ||||
|    if (procfile == NULL) | ||||
| -    return errno;
 | ||||
| +    {
 | ||||
| +      err = errno;
 | ||||
| +    fail:
 | ||||
| +      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
 | ||||
| +	{
 | ||||
| +	  errno = err;
 | ||||
| +	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
 | ||||
| +	}
 | ||||
| +      return err;
 | ||||
| +    }
 | ||||
|   | ||||
|    char *line = NULL; | ||||
|    size_t linelen = 0; | ||||
| @@ -317,19 +327,26 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
 | ||||
|    fclose (procfile); | ||||
|   | ||||
|    if (pid == 0) | ||||
| -    return ESRCH;
 | ||||
| +    {
 | ||||
| +      err = ESRCH;
 | ||||
| +      goto fail;
 | ||||
| +    }
 | ||||
|   | ||||
|    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) | ||||
| -    return errno;
 | ||||
| +    {
 | ||||
| +      err = errno;
 | ||||
| +      goto fail;
 | ||||
| +    }
 | ||||
|    struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg); | ||||
|    if (pid_arg == NULL) | ||||
|      { | ||||
|        closedir (dir); | ||||
| -      return ENOMEM;
 | ||||
| +      err = ENOMEM;
 | ||||
| +      goto fail;
 | ||||
|      } | ||||
|    pid_arg->dir = dir; | ||||
|    pid_arg->tid_attached = 0; | ||||
| diff --git a/tests/backtrace.c b/tests/backtrace.c
 | ||||
| index 1a4709b..ce0bd17 100644
 | ||||
| --- a/tests/backtrace.c
 | ||||
| +++ b/tests/backtrace.c
 | ||||
| @@ -1,5 +1,5 @@
 | ||||
|  /* Test program for unwinding of frames. | ||||
| -   Copyright (C) 2013 Red Hat, Inc.
 | ||||
| +   Copyright (C) 2013, 2014 Red Hat, Inc.
 | ||||
|     This file is part of elfutils. | ||||
|   | ||||
|     This file is free software; you can redistribute it and/or modify | ||||
| @@ -459,6 +459,9 @@ main (int argc __attribute__ ((unused)), char **argv)
 | ||||
|      }; | ||||
|    (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl); | ||||
|    assert (dwfl != NULL); | ||||
| +  /* We want to make sure the dwfl was properly attached.  */
 | ||||
| +  if (dwfl_pid (dwfl) < 0)
 | ||||
| +    error (2, 0, "dwfl_pid: %s", dwfl_errmsg (-1));
 | ||||
|    dump (dwfl); | ||||
|    dwfl_end (dwfl); | ||||
|    return 0; | ||||
| @ -1,7 +1,7 @@ | ||||
| Name: elfutils | ||||
| Summary: A collection of utilities and DSOs to handle compiled objects | ||||
| Version: 0.159 | ||||
| %global baserelease 3 | ||||
| %global baserelease 4 | ||||
| URL: https://fedorahosted.org/elfutils/ | ||||
| %global source_url http://fedorahosted.org/releases/e/l/elfutils/%{version}/ | ||||
| License: GPLv3+ and (GPLv2+ or LGPLv3+) | ||||
| @ -46,6 +46,7 @@ Source: %{?source_url}%{name}-%{version}.tar.bz2 | ||||
| 
 | ||||
| Patch1: %{?source_url}elfutils-portability.patch | ||||
| Patch2: elfutils-aarch64-user_regs_struct.patch | ||||
| Patch3: elfutils-0.159-argp-attach.patch | ||||
| 
 | ||||
| %if !%{compat} | ||||
| Release: %{baserelease}%{?dist} | ||||
| @ -209,6 +210,7 @@ sed -i.scanf-m -e 's/%m/%a/g' src/addr2line.c tests/line2addr.c | ||||
| %endif | ||||
| 
 | ||||
| %patch2 -p1 -b .aa64~1 | ||||
| %patch3 -p1 -b .argp-attach | ||||
| 
 | ||||
| find . -name \*.sh ! -perm -0100 -print | xargs chmod +x | ||||
| 
 | ||||
| @ -331,6 +333,9 @@ rm -rf ${RPM_BUILD_ROOT} | ||||
| %{_libdir}/libelf.a | ||||
| 
 | ||||
| %changelog | ||||
| * Tue Jun 10 2014 Mark Wielaard <mjw@redhat.com> - 0.159-4 | ||||
| - Add elfutils-0.159-argp-attach.patch (#1107654) | ||||
| 
 | ||||
| * Mon Jun 09 2014 Kyle McMartin <kyle@fedoraproject.org> - 0.159-3 | ||||
| - AArch64: handle new glibc-headers which provides proper GETREGSET structs. | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user