Skip site navigation (1)Skip section navigation (2)
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>