diff options
author | Theodore Ts'o <tytso@mit.edu> | 2006-12-22 13:38:38 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2006-12-22 13:38:38 -0500 |
commit | ec84b746f553f150935f82dd8d487517fcad745b (patch) | |
tree | 97575d759b8f98d21f064dd65f3aa2b98f23b6c4 /lib/et | |
parent | d2a3bf2ccc2df5167289e9fc084fec3cea78c950 (diff) | |
download | e2fsprogs-ec84b746f553f150935f82dd8d487517fcad745b.tar.gz |
Add debugging code to the com_err library
If the environment variable COMERR_DEBUG is set to 1, print out debugging
messages as error tables are added and removed from the com_err library.
If the COMERR_DEBUG_FILE environment variable is set (and the process is
not setuid) the debugging messages may be redirected to a file.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'lib/et')
-rw-r--r-- | lib/et/ChangeLog | 6 | ||||
-rw-r--r-- | lib/et/error_message.c | 78 |
2 files changed, 84 insertions, 0 deletions
diff --git a/lib/et/ChangeLog b/lib/et/ChangeLog index a43245cf..8940dd7c 100644 --- a/lib/et/ChangeLog +++ b/lib/et/ChangeLog @@ -1,3 +1,9 @@ +2006-12-22 Theodore Tso <tytso@mit.edu> + + * error_message.c (add_error_table, remove_error_table): Add + debugging so we can see what happens when various shared + libraries are loading and unloading error tables. + 2006-11-12 Theodore Tso <tytso@mit.edu> * compile_et.sh.in: Make sure locale environment variables are set to diff --git a/lib/et/error_message.c b/lib/et/error_message.c index 90d63c41..469ea964 100644 --- a/lib/et/error_message.c +++ b/lib/et/error_message.c @@ -20,6 +20,14 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#else +#define PR_GET_DUMPABLE 3 +#endif +#if (!defined(HAVE_PRCTL) && defined(linux)) +#include <sys/syscall.h> +#endif #include "com_err.h" #include "error_table.h" #include "internal.h" @@ -93,6 +101,60 @@ oops: } /* + * This routine will only return a value if the we are not running as + * a privileged process. + */ +static char *safe_getenv(const char *arg) +{ + if ((getuid() != geteuid()) || (getgid() != getegid())) + return NULL; +#if HAVE_PRCTL + if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) + return NULL; +#else +#if (defined(linux) && defined(SYS_prctl)) + if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) + return NULL; +#endif +#endif + +#ifdef HAVE___SECURE_GETENV + return __secure_getenv(arg); +#else + return getenv(arg); +#endif +} + +#define DEBUG_INIT 0x8000 +#define DEBUG_ADDREMOVE 0x0001 + +static int debug_mask = 0; +static FILE *debug_f = 0; + +static void init_debug(void) +{ + char *dstr; + char *fn; + + if (debug_mask & DEBUG_INIT) + return; + + dstr = getenv("COMERR_DEBUG"); + if (dstr) + debug_mask = strtoul(dstr, 0, 0); + + fn = safe_getenv("COMERR_DEBUG_FILE"); + if (fn) + debug_f = fopen(fn, "a"); + if (!debug_f) + debug_f = fopen("/dev/tty", "a"); + if (!debug_f) + debug_mask = 0; + + debug_mask |= DEBUG_INIT; +} + +/* * New interface provided by krb5's com_err library */ errcode_t add_error_table(const struct error_table * et) @@ -106,6 +168,12 @@ errcode_t add_error_table(const struct error_table * et) el->next = _et_dynamic_list; _et_dynamic_list = el; + init_debug(); + if (debug_mask & DEBUG_ADDREMOVE) + fprintf(debug_f, "add_error_table: %s (0x%p)\n", + error_table_name(et->base), + (const void *) et); + return 0; } @@ -117,6 +185,7 @@ errcode_t remove_error_table(const struct error_table * et) struct et_list *el = _et_dynamic_list; struct et_list *el2 = 0; + init_debug(); while (el) { if (el->table->base == et->base) { if (el2) /* Not the beginning of the list */ @@ -124,11 +193,20 @@ errcode_t remove_error_table(const struct error_table * et) else _et_dynamic_list = el->next; (void) free(el); + if (debug_mask & DEBUG_ADDREMOVE) + fprintf(debug_f, + "remove_error_table: %s (0x%p)\n", + error_table_name(et->base), + (const void *) et); return 0; } el2 = el; el = el->next; } + if (debug_mask & DEBUG_ADDREMOVE) + fprintf(debug_f, "remove_error_table FAILED: %s (0x%p)\n", + error_table_name(et->base), + (const void *) et); return ENOENT; } |