Apologies, as Frank pointed out to me, I hadn't updated the map file properly. Here is the corrected patch below.
--- We add a new internal function, __libdwfl_seterrno_details(), which accepts not just the error number but also an additional message to provide more details about the error. We also introduce a new interface function, dwfl_errmsg_details(), which can be used to access the details message. This new details string is meant as a way to provide additional dynamically generated feedback to the user. Signed-off-by: Jonathan Lebon <[email protected]> --- libdw/libdw.map | 5 +++++ libdwfl/dwfl_error.c | 27 +++++++++++++++++++++++++++ libdwfl/libdwfl.h | 3 +++ libdwfl/libdwflP.h | 2 ++ 4 files changed, 37 insertions(+) diff --git a/libdw/libdw.map b/libdw/libdw.map index 1d4cbb0..4a8ebf0 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -322,3 +322,8 @@ ELFUTILS_0.161 { dwarf_macro_getparamcnt; dwarf_macro_param; } ELFUTILS_0.160; + +ELFUTILS_0.162 { + global: + dwfl_errmsg_details; +} ELFUTILS_0.161; diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c index 56ec2b0..15b2ab5 100644 --- a/libdwfl/dwfl_error.c +++ b/libdwfl/dwfl_error.c @@ -43,6 +43,9 @@ /* The error number. */ static __thread int global_error; +/* Dynamically alloc'ed string with any additional details for error. */ +static __thread char* global_error_details = NULL; + int dwfl_errno (void) @@ -129,11 +132,28 @@ __libdwfl_canon_error (Dwfl_Error error) return canonicalize (error); } +static void +set_error_details(char* new_details) +{ + if (global_error_details != NULL) + free (global_error_details); + global_error_details = new_details; +} + void internal_function __libdwfl_seterrno (Dwfl_Error error) { global_error = canonicalize (error); + set_error_details(NULL); +} + +void +internal_function +__libdwfl_seterrno_details (Dwfl_Error error, char* details) +{ + global_error = canonicalize (error); + set_error_details(details); } @@ -170,3 +190,10 @@ dwfl_errmsg (error) ? error : DWFL_E_UNKNOWN_ERROR]]); } INTDEF (dwfl_errmsg) + +const char * +dwfl_errmsg_details () +{ + return global_error_details; +} +INTDEF (dwfl_errmsg_details) diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 2bb4f45..ad7b40e 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -102,6 +102,9 @@ extern int dwfl_errno (void); string is returned. */ extern const char *dwfl_errmsg (int err); +/* Return more details about the last error if available, or NULL otherwise. */ +extern const char *dwfl_errmsg_details (void); + /* Start reporting the current set of segments and modules to the library. All existing segments are wiped. Existing modules are marked to be diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 12ee116..17db534 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -103,6 +103,7 @@ typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error; extern int __libdwfl_canon_error (Dwfl_Error) internal_function; extern void __libdwfl_seterrno (Dwfl_Error) internal_function; +extern void __libdwfl_seterrno_details (Dwfl_Error, char*) internal_function; struct Dwfl { @@ -691,6 +692,7 @@ extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, /* Avoid PLT entries. */ INTDECL (dwfl_begin) INTDECL (dwfl_errmsg) +INTDECL (dwfl_errmsg_details) INTDECL (dwfl_errno) INTDECL (dwfl_addrmodule) INTDECL (dwfl_addrsegment) -- 2.1.0
