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 | 1 + libdwfl/dwfl_error.c | 27 +++++++++++++++++++++++++++ libdwfl/libdwfl.h | 3 +++ libdwfl/libdwflP.h | 2 ++ 4 files changed, 33 insertions(+) diff --git a/libdw/libdw.map b/libdw/libdw.map index 1d4cbb0..17c13ef 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -98,6 +98,7 @@ ELFUTILS_0.122 { dwfl_cumodule; dwfl_end; dwfl_errmsg; + dwfl_errmsg_details; dwfl_errno; dwfl_getdwarf; dwfl_getmodules; 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
