From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16444 invoked by alias); 9 May 2006 17:44:38 -0000 Received: (qmail 16426 invoked by uid 22791); 9 May 2006 17:44:36 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Tue, 09 May 2006 17:44:28 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1FdWG2-0002jO-AD; Tue, 09 May 2006 13:44:26 -0400 Date: Tue, 09 May 2006 17:44:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: RFA: More concise errors for missing shared libraries Message-ID: <20060509174426.GA9730@nevyn.them.org> Mail-Followup-To: gdb-patches@sourceware.org, Kevin Buettner Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.8i X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-05/txt/msg00169.txt.bz2 I've been working on a new GDB port to SymbianOS for a couple of months now. One of the quirks of this system, compared to a "typical" embedded target, is that it supports dynamic loading. The DLL format used is proprietary. I looked into making GDB read it, but even if we could, we wouldn't get useful information from it. There's no usable symbol table. Instead we normally open ELF versions of the DLLs. I've got various changes in my tree to support this (it's on gdb-csl-symbian-20060226-branch if you're interested), which I hope I'll be submitting soon. This patch is one of them. One of the quirks of SymbianOS compared to a traditional hosted target is that it's quite likely that GDB will have no symbol file at all for many of the loaded libraries. A ROM image may contain many DLLs, presented as a virtual filesystem, which are effectively preloaded into the memory space of every process. A user probably only has symbol files for his own DLLs, not the DLLs which provide operating system services. So, the behavior of GDB when shared libraries can not be found is much more important than on other targets. Right now this is really noisy. We get a two-line error message for each library from update_solib_list when we detect the new library, and another one from solib_read_symbols later. This patch condenses those into a single warning: warning: Could not load shared library symbols for 2 libraries, e.g. /lib/libnss_dns.so.2. Do you need "set solib-search-path" or "set solib-absolute-prefix"? It gives the name of the first new library; if you want more information, you can run "info shared". I toyed with hiding missing shared libraries in the default "info shared" output and adding "info shared all", but decided against it - I expect that eventually most of this will be wrapped up in an IDE, and the IDE can encode that sort of Symbian-specific front-end knowledge. Or maybe I'll think about it some more later. Some more detailed examples are at the bottom of this message. While putting them together I noticed that the current code can also read shared libraries outside of solib-absolute-prefix unintentionally, because failure to open the library leaves so_name pointing to the unmodified filename; that's also fixed as a side effect of this patch. While I was in this code, I removed the so_list from_tty flag; it's only used in one place, and really we're interested in the current version of from_tty at that point, not the version when the library was opened. The new TRY_CATCH makes this much easier. Is this OK? Do you see a way to improve the output further? === Using an unmodified GDB, with all the libraries and variables in their normal places, I get: (gdb) r Starting program: /usr/bin/telnet (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) All normal. === With solib-absolute-prefix pointing to a directory that has /lib64/ld-linux-x86-64.so.2 (so that the initial breakpoint can be set), but no other libraries: (gdb) set solib-absolute-prefix . (gdb) r Starting program: /usr/bin/telnet Error while mapping shared library sections: /usr/lib/libncurses.so.5: No such file or directory. Error while mapping shared library sections: /usr/lib/libstdc++.so.6: No such file or directory. Error while mapping shared library sections: /lib/libm.so.6: No such file or directory. Error while mapping shared library sections: /lib/libgcc_s.so.1: No such file or directory. Error while mapping shared library sections: /lib/libc.so.6: No such file or directory. Error while mapping shared library sections: /lib/libdl.so.2: No such file or directory. (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) Error while mapping shared library sections: /lib/libnss_files.so.2: No such file or directory. (no debugging symbols found) (no debugging symbols found) Error while mapping shared library sections: /lib/libnss_dns.so.2: No such file or directory. Error while mapping shared library sections: /lib/libresolv.so.2: No such file or directory. (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) Program received signal SIGINT, Interrupt. 0x00002b19d79a7802 in ?? () (gdb) i shared >From To Syms Read Shared Object Library Yes /usr/lib/libncurses.so.5 Yes /usr/lib/libstdc++.so.6 Yes /lib/libm.so.6 Yes /lib/libgcc_s.so.1 Yes /lib/libc.so.6 Yes /lib/libdl.so.2 0x00002b19d71dfa80 0x00002b19d71f0957 Yes ./lib64/ld-linux-x86-64.so.2 Yes /lib/libnss_files.so.2 Yes /lib/libnss_dns.so.2 Yes /lib/libresolv.so.2 Now, there's two things wrong with this output. One of them is cosmetic, but annoying: we got a two-line error for every single library. Another is that we've somehow read symbols from the host libraries despite solib-absolute-prefix. (I didn't notice that until I was writing this email, but it also happens to be fixed by this patch.) If the library weren't present on the host system at all, instead of reading the syms, we'd issue a second two-line error message for each library. === With the patch applied, and solib-absolute-prefix set to the same temporary directory: (gdb) set solib-absolute-prefix . (gdb) r Starting program: /usr/bin/telnet warning: Could not load shared library symbols for 6 libraries, e.g. /usr/lib/libncurses.so.5. Do you need "set solib-search-path" or "set solib-absolute-prefix"? (no debugging symbols found) warning: Could not load shared library symbols for /lib/libnss_files.so.2. Do you need "set solib-search-path" or "set solib-absolute-prefix"? warning: Could not load shared library symbols for 2 libraries, e.g. /lib/libnss_dns.so.2. Do you need "set solib-search-path" or "set solib-absolute-prefix"? telnet> Program received signal SIGINT, Interrupt. 0x00002b9e84626802 in ?? () (gdb) i shared >From To Syms Read Shared Object Library No /usr/lib/libncurses.so.5 No /usr/lib/libstdc++.so.6 No /lib/libm.so.6 No /lib/libgcc_s.so.1 No /lib/libc.so.6 No /lib/libdl.so.2 0x00002b9e83e5ea80 0x00002b9e83e6f957 Yes ./lib64/ld-linux-x86-64.so.2 No /lib/libnss_files.so.2 No /lib/libnss_dns.so.2 No /lib/libresolv.so.2 We still get multiple warning messages, but that's because libnss_files and libnss_dns are dlopen'd later. The first group of messages is condensed to a single line (with suggestion). -- Daniel Jacobowitz CodeSourcery 2006-05-09 Daniel Jacobowitz * bsd-uthread.c (bsd_uthread_solib_loaded): Always pass 0 for from_tty. * solib.c: Include "exceptions.h". (solib_map_sections): Throw NOT_FOUND_ERROR if appropriate. (symbol_add_stub): Delete. (solib_read_symbols): Use TRY_CATCH. Inline symbol_add_stub. Use current from_tty, not a copy from the so_list. Don't warn a second time for a missing library. (update_solib_list): Don't save from_tty. Use TRY_CATCH. Print out a single warning for all missing libraries. * solist.h (struct so_list): Remove from_tty. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.812 diff -u -p -r1.812 Makefile.in --- Makefile.in 5 May 2006 22:39:12 -0000 1.812 +++ Makefile.in 9 May 2006 15:52:47 -0000 @@ -2579,7 +2579,7 @@ solib.o: solib.c $(defs_h) $(gdb_string_ $(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \ $(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \ $(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \ - $(observer_h) $(readline_h) + $(observer_h) $(readline_h) $(exceptions_h) solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \ $(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \ $(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) Index: bsd-uthread.c =================================================================== RCS file: /cvs/src/src/gdb/bsd-uthread.c,v retrieving revision 1.7 diff -u -p -r1.7 bsd-uthread.c --- bsd-uthread.c 17 Dec 2005 22:33:59 -0000 1.7 +++ bsd-uthread.c 9 May 2006 15:52:47 -0000 @@ -237,7 +237,7 @@ bsd_uthread_solib_loaded (struct so_list { if (strncmp (so->so_original_name, *names, strlen (*names)) == 0) { - solib_read_symbols (so, so->from_tty); + solib_read_symbols (so, 0); if (bsd_uthread_activate (so->objfile)) { Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.84 diff -u -p -r1.84 solib.c --- solib.c 25 Feb 2006 04:36:39 -0000 1.84 +++ solib.c 9 May 2006 15:52:48 -0000 @@ -45,6 +45,7 @@ #include "exec.h" #include "solist.h" #include "observer.h" +#include "exceptions.h" #include "readline/readline.h" /* Architecture-specific operations. */ @@ -273,6 +274,11 @@ solib_map_sections (void *arg) if (scratch_chan < 0) { + /* Throw a more specific error if the file could not be found, so + that we can accumulate messages about missing libraries. */ + if (errno == ENOENT) + throw_error (NOT_FOUND_ERROR, "%s", safe_strerror (errno)); + perror_with_name (filename); } @@ -381,31 +387,6 @@ master_so_list (void) } -/* A small stub to get us past the arg-passing pinhole of catch_errors. */ - -static int -symbol_add_stub (void *arg) -{ - struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ - struct section_addr_info *sap; - - /* Have we already loaded this shared object? */ - ALL_OBJFILES (so->objfile) - { - if (strcmp (so->objfile->name, so->so_name) == 0) - return 1; - } - - sap = build_section_addr_info_from_section_table (so->sections, - so->sections_end); - - so->objfile = symbol_file_add (so->so_name, so->from_tty, - sap, 0, OBJF_SHARED); - free_section_addr_info (sap); - - return (1); -} - /* Read in symbols for shared object SO. If FROM_TTY is non-zero, be chatty about it. Return non-zero if any symbols were actually loaded. */ @@ -420,9 +401,44 @@ solib_read_symbols (struct so_list *so, } else { - if (catch_errors (symbol_add_stub, so, - "Error while reading shared library symbols:\n", - RETURN_MASK_ALL)) + volatile struct gdb_exception e; + + TRY_CATCH (e, RETURN_MASK_ERROR) + { + struct section_addr_info *sap; + + /* Could we find a file for this shared library? If we + couldn't, don't try to open it again. */ + if (so->abfd == NULL) + throw_error (NOT_FOUND_ERROR, "%s", safe_strerror (errno)); + + /* Have we already loaded this shared object? */ + ALL_OBJFILES (so->objfile) + { + if (strcmp (so->objfile->name, so->so_name) == 0) + break; + } + if (so->objfile != NULL) + break; + + sap = build_section_addr_info_from_section_table (so->sections, + so->sections_end); + so->objfile = symbol_file_add (so->so_name, from_tty, + sap, 0, OBJF_SHARED); + free_section_addr_info (sap); + } + + if (e.reason == RETURN_ERROR && e.error == NOT_FOUND_ERROR) + /* We've already warned about this library, when trying to + open it. */ + return 0; + else if (e.reason < 0) + { + if (from_tty) + exception_fprintf + (gdb_stderr, e, _("Error while reading shared library symbols:\n")); + } + else { if (from_tty) printf_unfiltered (_("Loaded symbols for %s\n"), so->so_name); @@ -568,6 +584,9 @@ update_solib_list (int from_tty, struct to GDB's shared object list. */ if (inferior) { + int not_found = 0; + const char *not_found_filename = NULL; + struct so_list *i; /* Add the new shared objects to GDB's list. */ @@ -576,12 +595,25 @@ update_solib_list (int from_tty, struct /* Fill in the rest of each of the `struct so_list' nodes. */ for (i = inferior; i; i = i->next) { - i->from_tty = from_tty; + volatile struct gdb_exception e; - /* Fill in the rest of the `struct so_list' node. */ - catch_errors (solib_map_sections, i, - "Error while mapping shared library sections:\n", - RETURN_MASK_ALL); + TRY_CATCH (e, RETURN_MASK_ERROR) + { + /* Fill in the rest of the `struct so_list' node. */ + solib_map_sections (i); + } + + if (e.reason == RETURN_ERROR && e.error == NOT_FOUND_ERROR) + { + not_found++; + if (not_found_filename == NULL) + not_found_filename = i->so_original_name; + } + else if (e.reason < 0) + { + exception_fprintf (gdb_stderr, e, + _("Error while mapping shared library sections:\n")); + } /* If requested, add the shared object's sections to the TARGET's section table. Do this immediately after mapping the object so @@ -603,6 +635,24 @@ update_solib_list (int from_tty, struct loaded now that we've added it to GDB's tables. */ observer_notify_solib_loaded (i); } + + /* If a library was not found, issue an appropriate warning + message. We have to use a single call to warning () in case + the front end does something special with warnings, e.g. pop + up a dialog box. It Would Be Nice if we could get a + "warning: " prefix on each line in the CLI front end, + though - it doesn't stand out well. */ + + if (not_found == 1) + warning (_("\ +Could not load shared library symbols for %s.\n\ +Do you need \"set solib-search-path\" or \"set solib-absolute-prefix\"?"), + not_found_filename); + else if (not_found > 1) + warning (_("\ +Could not load shared library symbols for %d libraries, e.g. %s.\n\ +Do you need \"set solib-search-path\" or \"set solib-absolute-prefix\"?"), + not_found, not_found_filename); } } Index: solist.h =================================================================== RCS file: /cvs/src/src/gdb/solist.h,v retrieving revision 1.12 diff -u -p -r1.12 solist.h --- solist.h 17 Dec 2005 22:34:02 -0000 1.12 +++ solist.h 9 May 2006 15:52:48 -0000 @@ -61,7 +61,6 @@ struct so_list bfd *abfd; char symbols_loaded; /* flag: symbols read in yet? */ - char from_tty; /* flag: print msgs? */ struct objfile *objfile; /* objfile for loaded lib */ struct section_table *sections; struct section_table *sections_end;