diff options
author | Mark Wielaard <mjw@redhat.com> | 2014-06-11 15:14:23 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2014-06-11 15:31:41 +0200 |
commit | 14beac3b6f22b8d7a054980f74c4f8d33b969fc4 (patch) | |
tree | 829d37f7f338c037c35e82d43fa86e34b1977324 /libdwfl/dwfl_frame.c | |
parent | 824f393411acc4596ab557b6e7bff9e48c61f951 (diff) | |
download | elfutils-14beac3b6f22b8d7a054980f74c4f8d33b969fc4.tar.gz |
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>
Diffstat (limited to 'libdwfl/dwfl_frame.c')
-rw-r--r-- | libdwfl/dwfl_frame.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c index fd0b9aeb..f6f86c0d 100644 --- a/libdwfl/dwfl_frame.c +++ b/libdwfl/dwfl_frame.c @@ -1,5 +1,5 @@ /* Get Dwarf Frame state for target PID or core file. - 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 @@ -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) { |