Date: Sun, 3 Jan 2010 18:03:44 +1100 (EST) From: Peter Jeremy <peterjeremy@acm.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/142258: [patch] Add ability to log or print rtld errors Message-ID: <201001030703.o0373iqA082898@server.vk2pj.dyndns.org> Resent-Message-ID: <201001030710.o037A0RJ037501@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 142258 >Category: bin >Synopsis: [patch] Add ability to log or print rtld errors >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Jan 03 07:10:00 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Peter Jeremy >Release: FreeBSD 8.0-STABLE amd64 >Organization: n/a >Environment: System: FreeBSD server.vk2pj.dyndns.org 8.0-STABLE FreeBSD 8.0-STABLE #11: Mon Nov 30 16:36:34 EST 2009 root@server.vk2pj.dyndns.org:/var/obj/usr/src/sys/server amd64 >Description: ld-elf.so.1 records errors via _rtld_error() and can return the latest error to the application via dlerror(). If the application doesn't choose to report the error to the user, it can be almost impossible to determine why a program is failing - eg if a symbol if undefined. The attached patch provides two mechanisms to access error messages independent of the application: 1) A new environment variable LD_PRINT_ERROR causes _rtld_error() to automatically log any message. 2) Messages logged via _rtld_error() are passed to utrace() if tracing is enabled (via LD_UTRACE). >How-To-Repeat: With the patch in place: server% LD_PRINT_ERROR=x sh -c 'ls ~fred' RTLD Error: Shared object "nss_files.so.1" not found, required by "sh" RTLD Error: Shared object "nss_files.so.1" not found, required by "sh" RTLD Error: Shared object "nss_dns.so.1" not found, required by "sh" RTLD Error: Shared object "nss_dns.so.1" not found, required by "sh" RTLD Error: Shared object "nss_dns.so.1" not found, required by "sh" RTLD Error: Undefined symbol "_nss_cache_cycle_prevention_function" ls: ~fred: No such file or directory server% (Note that the duplicated messages appear to be caused by multiple identical calls to _rtld_error()). >Fix: Index: rtld.1 =================================================================== RCS file: /usr/ncvs/src/libexec/rtld-elf/rtld.1,v retrieving revision 1.49.2.1 diff -u -r1.49.2.1 rtld.1 --- rtld.1 3 Aug 2009 08:13:06 -0000 1.49.2.1 +++ rtld.1 3 Jan 2010 06:15:22 -0000 @@ -154,6 +154,11 @@ will be searched first followed by the set of built-in standard directories. This variable is unset for set-user-ID and set-group-ID programs. +.It Ev LD_PRINT_ERROR +When set to a nonempty string, causes +.Nm +to print any error messages that would be available to the application via +.Xr dlopen 3 . .It Ev LD_BIND_NOW When set to a nonempty string, causes .Nm Index: rtld.c =================================================================== RCS file: /usr/ncvs/src/libexec/rtld-elf/rtld.c,v retrieving revision 1.139.2.2 diff -u -r1.139.2.2 rtld.c --- rtld.c 20 Oct 2009 13:26:58 -0000 1.139.2.2 +++ rtld.c 3 Jan 2010 06:24:14 -0000 @@ -164,6 +164,7 @@ static char *ld_elf_hints_path; /* Environment variable for alternative hints path */ static char *ld_tracing; /* Called from ldd to print libs */ static char *ld_utrace; /* Use utrace() to log events. */ +static char *ld_printerror; /* Report _rtld_error() messages to stdout */ static Obj_Entry *obj_list; /* Head of linked list of shared objects */ static Obj_Entry **obj_tail; /* Link field of last object in list */ static Obj_Entry *obj_main; /* The main program shared object */ @@ -244,6 +245,10 @@ (dlp)->num_alloc = obj_count, \ (dlp)->num_used = 0) +/* + * The following macros and struct utrace_rtld must be kept aligned with + * the equivalent code in kdump.c + */ #define UTRACE_DLOPEN_START 1 #define UTRACE_DLOPEN_STOP 2 #define UTRACE_DLCLOSE_START 3 @@ -254,6 +259,7 @@ #define UTRACE_PRELOAD_FINISHED 8 #define UTRACE_INIT_CALL 9 #define UTRACE_FINI_CALL 10 +#define UTRACE_RTLD_ERROR 11 struct utrace_rtld { char sig[4]; /* 'RTLD' */ @@ -384,6 +390,7 @@ (ld_elf_hints_path != NULL); ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS"); ld_utrace = getenv(LD_ "UTRACE"); + ld_printerror = getenv(LD_ "PRINT_ERROR"); if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0) ld_elf_hints_path = _PATH_ELF_HINTS; @@ -612,6 +619,9 @@ vsnprintf(buf, sizeof buf, fmt, ap); error_message = buf; va_end(ap); + if (ld_printerror != NULL && ld_printerror != '\0') + printf("RTLD Error: %s\n", error_message); + LD_UTRACE(UTRACE_RTLD_ERROR, NULL, NULL, 0, 0, error_message); } /* Index: kdump.c =================================================================== RCS file: /usr/ncvs/src/usr.bin/kdump/kdump.c,v retrieving revision 1.45.2.2 diff -u -r1.45.2.2 kdump.c --- kdump.c 22 Nov 2009 16:13:16 -0000 1.45.2.2 +++ kdump.c 3 Jan 2010 06:21:51 -0000 @@ -1009,6 +1009,10 @@ cs->user ? "user" : "kernel"); } +/* + * The following macros and struct utrace_rtld must be kept aligned with + * the equivalent code in rtld.c + */ #define UTRACE_DLOPEN_START 1 #define UTRACE_DLOPEN_STOP 2 #define UTRACE_DLCLOSE_START 3 @@ -1019,6 +1023,7 @@ #define UTRACE_PRELOAD_FINISHED 8 #define UTRACE_INIT_CALL 9 #define UTRACE_FINI_CALL 10 +#define UTRACE_RTLD_ERROR 11 struct utrace_rtld { char sig[4]; /* 'RTLD' */ @@ -1097,6 +1102,10 @@ printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, ut->name); break; + case UTRACE_RTLD_ERROR: + printf("RTLD: error: %s\n", ut->name); + break; + default: p += 4; len -= 4; >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001030703.o0373iqA082898>