summaryrefslogtreecommitdiff
path: root/libdwfl/dwfl_frame.c
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-06-11 15:14:23 +0200
committerMark Wielaard <mjw@redhat.com>2014-06-11 15:31:41 +0200
commit14beac3b6f22b8d7a054980f74c4f8d33b969fc4 (patch)
tree829d37f7f338c037c35e82d43fa86e34b1977324 /libdwfl/dwfl_frame.c
parent824f393411acc4596ab557b6e7bff9e48c61f951 (diff)
downloadelfutils-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.c46
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)
{