From d1cf9ea2c4d424f77e8ed5efa5a8c3a2b1db219d Mon Sep 17 00:00:00 2001 From: Maxim Sobolev Date: Sat, 19 Oct 2002 10:18:29 +0000 Subject: [PATCH] Fix a problem with RTLD_TRACE flag to dlopen(3), which sometimes can return even if there was no error occured (when trying to dlopen(3) object that already linked into executable which does dlopen(3) call). This is more proper fix for `ldd /usr/lib/libc.so' problem, because the new behaviour conforms to documentation. Remove workaround from ldd.c (rev.1.32). PR: 35099 Submitted by: Nathan Hawkins MFC after: 1 week --- libexec/rtld-elf/rtld.c | 14 ++++++++------ usr.bin/ldd/ldd.c | 9 ++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index a007ff5c1d1b..d7f243ac8e52 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1605,11 +1605,8 @@ dlopen(const char *name, int mode) assert(*old_obj_tail == obj); result = load_needed_objects(obj); - if (result != -1 && ld_tracing) { - trace_loaded_objects(obj); - wlock_release(); - exit(0); - } + if (result != -1 && ld_tracing) + goto trace; if (result == -1 || (init_dag(obj), relocate_objects(obj, mode == RTLD_NOW, @@ -1623,7 +1620,8 @@ dlopen(const char *name, int mode) /* Make list of init functions to call. */ initlist_add_objects(obj, &obj->next, &initlist); } - } + } else if (ld_tracing) + goto trace; } GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL); @@ -1635,6 +1633,10 @@ dlopen(const char *name, int mode) objlist_clear(&initlist); wlock_release(); return obj; +trace: + trace_loaded_objects(obj); + wlock_release(); + exit(0); } void * diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c index 68f99887d298..8e5e5d2f2bcf 100644 --- a/usr.bin/ldd/ldd.c +++ b/usr.bin/ldd/ldd.c @@ -220,13 +220,12 @@ main(int argc, char *argv[]) } break; case 0: - if (is_shlib) { - if (dlopen(*argv, RTLD_TRACE)) - _exit(0); /* libc.so */ - warnx("%s: %s", *argv, dlerror()); - } else { + if (is_shlib == 0) { execl(*argv, *argv, (char *)NULL); warn("%s", *argv); + } else { + dlopen(*argv, RTLD_TRACE); + warnx("%s: %s", *argv, dlerror()); } _exit(1); }