Bug 28330 - gdbinit file should be loaded before core file
Summary: gdbinit file should be loaded before core file
Status: RESOLVED INVALID
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 9.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-09-10 11:55 UTC by Thomas De Schampheleire
Modified: 2021-09-10 15:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas De Schampheleire 2021-09-10 11:55:44 UTC
In a cross-compilation context, gdb will not be able to load all shared libraries without additional information like a sysroot. Such context-specific settings can be passed via gdbinit files specified on the gdb command-line via '-x' (--command).

Buildroot (a tool to help build images for embedded Linux), for example, will create a gdbinit file that sets the right sysroot ('set sysroot').

However, the gdbinit file(s) passed on the gdb command-line are currently read _after_ the core file, which leads to a large number of warning messages, which is very confusing to unwary users:


$ cross-gdb myapp mycorefile
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=i686-buildroot-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from myapp...

warning: core file may not match specified executable file.
[New LWP 602]
[New LWP 8307]

warning: .dynamic section for "/lib/libstdc++.so.6" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/librt.so.1" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libm.so.6" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libgcc_s.so.1" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libc.so.6" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/ld-linux.so.2" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libanl.so.1" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libdl.so.2" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libpthread.so.0" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/usr/lib/libz.so.1" is not at the expected address (wrong library or version mismatch?)

warning: .dynamic section for "/lib/libnss_files.so.2" is not at the expected address (wrong library or version mismatch?)

warning: Could not load shared library symbols for 17 libraries, e.g. [...]
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `myapp args'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0xf7fd3a29 in __kernel_vsyscall ()
[Current thread is 1 (LWP 602)]
show warning: File ".../i686-buildroot-linux-gnu/sysroot/lib/libstdc++.so.6.0.24-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
        add-auto-load-safe-path .../i686-buildroot-linux-gnu/sysroot/lib/libstdc++.so.6.0.24-gdb.py
line to your configuration file "/home/me/.gdbinit".
To completely disable this security protection add
        set auto-load safe-path /
line to your configuration file "/home/me/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
        info "(gdb)Auto-loading safe path"
(gdb)


When you check e.g. 'info shared' from the gdb prompt, all libraries are loaded correctly (thanks to the sysroot specified in gdbinit file), so these warnings are actually invalid and confusing.

With respect to the loading of the C++ pretty-printers, there is an actual problem caused by the core file being loaded before the gdbinit files: even though the 'auto-load-safe-path' was set to a correct value from the gdbinit files, the pretty-printer file 'libstdc++.so.6.0.24-gdb.py' file was _NOT_ loaded, because the 'auto-load-safe-path' at the time of loading the core file did not _yet_ include the correct value, and this is not re-attempted at a later stage.


(gdb) show auto-load safe-path 
List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load:[...]/i686-buildroot-linux-gnu/sysroot.
(gdb) show sysroot
The current system root is "[...]/i686-buildroot-linux-gnu/sysroot".
(gdb) info pretty-printer
global pretty-printers:
  builtin
    mpx_bound128



When I use the same gdb and gdbinit files without core file, connecting to an actual target, the pretty printers are loaded correctly:

(gdb) info pretty-printer
global pretty-printers:
  builtin
    mpx_bound128
objfile [...]/i686-buildroot-linux-gnu/sysroot/lib/libstdc++.so.6 pretty-printers:
  libstdc++-v6
    __gnu_cxx::_Slist_iterator
    __gnu_cxx::__7::_Slist_iterator
    __gnu_cxx::__7::__normal_iterator
    __gnu_cxx::__7::slist
    __gnu_cxx::__normal_iterator
    __gnu_cxx::slist
    [...]


These problems would be fixed if the gdbinit files specified on the command-line were loaded before the core file is read.

I read in the NEWS file that in gdb 4.6, a similar change was already done for the $HOME/.gdbinit file, but _not_ for other gdbinit files. It is unclear to me what the reason is for this.
Comment 1 Simon Marchi 2021-09-10 14:27:27 UTC
I'm a bit confused, because you talk about files loaded using -x, but your example doesn't show any -x passed to gdb.  Are you talking about files loaded using -x, or gdbinit files loaded automatically, such as the one in $HOME/.gdbinit?

If you are talking about -x, then there exists both -ix and -eix that can be used to load files earlier in the startup process, maybe that can help.
Comment 2 Thomas De Schampheleire 2021-09-10 14:50:50 UTC
(In reply to Simon Marchi from comment #1)
> I'm a bit confused, because you talk about files loaded using -x, but your
> example doesn't show any -x passed to gdb.  Are you talking about files
> loaded using -x, or gdbinit files loaded automatically, such as the one in
> $HOME/.gdbinit?
> 
> If you are talking about -x, then there exists both -ix and -eix that can be
> used to load files earlier in the startup process, maybe that can help.

Sorry for the confusion.

In the example, `cross-gdb` is actually a wrapper around the real gdb binary, passing one or more `-x path-to-gdbinit` options.

I had tried '-ix' / '--init-command' before, but must have drawn an incorrect conclusion, because now I tried it again and indeed it works.

Moreover, when using '-x', I now notice that the error about auto-load-safe-path can actually be solved by _first_ setting the auto-load-safe-path, and _then_ setting the sysroot. When using '-ix' this order no longer matters.

So, problem solved, thanks a lot, and sorry for the noise.
Comment 3 Simon Marchi 2021-09-10 15:12:22 UTC
Ok, that's good to hear.  Perhaps the -ix behavior changed across the years, I don't know.