Date: 29 Sep 2001 08:05:10 -0000 From: Mike Meyer <mwm@mired.org> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/30908: [PATCH] Tweak ldd to provide more information if requested Message-ID: <20010929080510.89935.qmail@guru.mired.org>
next in thread | raw e-mail | index | archive | help
>Number: 30908 >Category: bin >Synopsis: [PATCH] Tweak ldd to provide more information if requested >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: Sat Sep 29 01:10:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Mike Meyer >Release: FreeBSD 4.4-RC i386 >Organization: Meyer Consulting >Environment: System: FreeBSD guru.mired.org 4.4-RC FreeBSD 4.4-RC #17: Wed Sep 19 02:20:57 CDT 2001 mwm@guru.mired.org:/usr/src/sys/compile/GURU i386 >Description: If one of the dynamically loaded libraries loads a library that's been updated, ldd provides almost no help in finding the library that's asking for an out-of-date library. The particular example that triggered this was galleon looking for both libpng.so.4 and libpng.so.5, because one of the libraries was looking for libpng.so.4 even though the binary proper was using libpng.so.4 >How-To-Repeat: Try "ldd /usr/bin/k5admin" and note that it uses ncurses, even though the k5admin object doesn't refer to that library in any way. In this particular case, it's pretty obvious that libreadline is dragging it in. It isn't always quite so obvious, especially for large X programs. >Fix: The attached diff adds code to ld-elf.so.1 to check a new environment variable when tracing, and if it is set to print the name of each object before printing the objects that it needs. There are no changes if it isn't tracing loaded objects. The patch also adds a flag to ldd to cause it to set this environment variable and not print the name of the file being examined, as rt-elf.ld.so.1 will do that in this case. The patch also updates the manual pages to reflect these changes. diff -ru /usr/src/libexec/rtld-elf/rtld.1 /tmp/src/libexec/rtld-elf/rtld.1 --- /usr/src/libexec/rtld-elf/rtld.1 Sat Aug 18 08:31:31 2001 +++ /tmp/src/libexec/rtld-elf/rtld.1 Sat Sep 29 01:56:29 2001 @@ -99,6 +99,11 @@ .Nm to exit after loading the shared objects and printing a summary which includes the absolute pathnames of all objects, to standard output. +.It Ev LD_TRACE_LOADED_OBJECTS_ALL +When set to a nonempty string, causes +.Nm +to expand the summary to indicate which objects caused each object to +be loaded. .It Ev LD_TRACE_LOADED_OBJECTS_FMT1 .It Ev LD_TRACE_LOADED_OBJECTS_FMT2 When set, these variables are interpreted as format strings a la diff -ru /usr/src/libexec/rtld-elf/rtld.c /tmp/src/libexec/rtld-elf/rtld.c --- /usr/src/libexec/rtld-elf/rtld.c Sat Sep 29 00:17:36 2001 +++ /tmp/src/libexec/rtld-elf/rtld.c Sat Sep 29 02:13:12 2001 @@ -1956,7 +1956,7 @@ static void trace_loaded_objects(Obj_Entry *obj) { - char *fmt1, *fmt2, *fmt, *main_local; + char *fmt1, *fmt2, *fmt, *main_local, *list_containers; int c; if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) @@ -1968,14 +1968,18 @@ if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL) fmt2 = "\t%o (%x)\n"; + list_containers = getenv("LD_TRACE_LOADED_OBJECTS_ALL"); + for (; obj; obj = obj->next) { Needed_Entry *needed; char *name, *path; bool is_lib; + if (list_containers && obj->needed != NULL) + printf("%s:\n", obj->path); for (needed = obj->needed; needed; needed = needed->next) { if (needed->obj != NULL) { - if (needed->obj->traced) + if (needed->obj->traced && !list_containers) continue; needed->obj->traced = true; path = needed->obj->path; diff -ru /usr/src/usr.bin/ldd/ldd.1 /tmp/src/usr.bin/ldd/ldd.1 --- /usr/src/usr.bin/ldd/ldd.1 Sat Aug 18 08:32:04 2001 +++ /tmp/src/usr.bin/ldd/ldd.1 Sat Sep 29 02:06:22 2001 @@ -8,6 +8,7 @@ .Nd list dynamic object dependencies .Sh SYNOPSIS .Nm +.Op Fl a .Op Fl v .Op Fl f Ar format .Ar program ... @@ -32,6 +33,11 @@ See .Xr rtld 1 for a list of recognized conversion characters. +.Pp +The +.Fl a +option displays the list of all objects that are needed by each loaded +object. This option does not work with a.out binaries. .Pp The .Fl v diff -ru /usr/src/usr.bin/ldd/ldd.c /tmp/src/usr.bin/ldd/ldd.c --- /usr/src/usr.bin/ldd/ldd.c Sun Jul 15 13:27:24 2001 +++ /tmp/src/usr.bin/ldd/ldd.c Sat Sep 29 02:07:48 2001 @@ -48,7 +48,7 @@ void usage() { - fprintf(stderr, "usage: ldd [-v] [-f format] program ...\n"); + fprintf(stderr, "usage: ldd [-a] [-v] [-f format] program ...\n"); exit(1); } @@ -60,10 +60,13 @@ char *fmt1 = NULL, *fmt2 = NULL; int rval; int c; - int vflag = 0; + int vflag = 0, aflag = 0; - while ((c = getopt(argc, argv, "vf:")) != -1) { + while ((c = getopt(argc, argv, "avf:")) != -1) { switch (c) { + case 'a': + aflag++; + break; case 'v': vflag++; break; @@ -179,7 +182,8 @@ } setenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1); - if (fmt1 == NULL && fmt2 == NULL) + if (aflag) setenv("LD_TRACE_LOADED_OBJECTS_ALL", "1", 1); + else if (fmt1 == NULL && fmt2 == NULL) /* Default formats */ printf("%s:\n", *argv); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010929080510.89935.qmail>