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>
