Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading python support in gdb

I've got a problem with getting python-specific commands working in gdb. I've got the general python support included:

(gdb) python print(True)
True

I've got the standard scripts installed:

$ ls /usr/share/gdb/python/gdb/
command  FrameDecorator.py  FrameIterator.py  frames.py  function  __init__.py  printer  printing.py  prompt.py  __pycache__  types.py  unwinder.py  xmethod.py

I made sure the loading is enabled with all paths I could:

$ cat ~/.gdbinit 
add-auto-load-safe-path /usr/share/gdb/python/gdb/
add-auto-load-safe-path /usr/share/gdb/python/
add-auto-load-safe-path /usr/share/gdb/
set auto-load python-scripts on

But for some reason gdb still doesn't like this:

(gdb) info auto-load 
gdb-scripts:  No auto-load scripts.
guile-scripts:  No auto-load scripts.
libthread-db:  No auto-loaded libthread-db.
local-gdbinit:  Local .gdbinit file was not found.
python-scripts:  No auto-load scripts.

I'd like to get the py-bt command working after loading gdb.

like image 803
viraptor Avatar asked Nov 02 '16 23:11

viraptor


1 Answers

The py-bt and related commands are usually defined in a GDB script file python*-gdb.py, which tends to be present in /usr/share/gdb/auto-load/usr/bin/. If those commands are not available for you in GDB when debugging a Python object file, it means that the script which contains them was not auto-loaded.

To find out why, enable auto-load debugging:

(gdb) set debug auto-load

and try to load Python executable:

(gdb) file python3

You should see output similar to this:

Reading symbols from python3...Reading symbols from /usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug...done.
auto-load: Attempted file "/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.gdb" does not exist.
auto-load: Expanded $-variables to "/usr/lib/debug:/usr/share/gdb/auto-load".
auto-load: Searching 'set auto-load scripts-directory' path "$debugdir:$datadir/auto-load".
auto-load: Attempted file "/usr/lib/debug/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.gdb" does not exist.
auto-load: Attempted file "/usr/share/gdb/auto-load/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.gdb" does not exist.
auto-load: Attempted file "/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.py" does not exist.
auto-load: Expanded $-variables to "/usr/lib/debug:/usr/share/gdb/auto-load".
auto-load: Searching 'set auto-load scripts-directory' path "$debugdir:$datadir/auto-load".
auto-load: Attempted file "/usr/lib/debug/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.py" does not exist.
auto-load: Attempted file "/usr/share/gdb/auto-load/usr/lib/debug/.build-id/58/bce0c98a07039868053ed4b27e79959caadb9d.debug-gdb.py" does not exist.
done.
auto-load: Attempted file "/usr/bin/python3.6-gdb.gdb" does not exist.
auto-load: Expanded $-variables to "/usr/lib/debug:/usr/share/gdb/auto-load".
auto-load: Searching 'set auto-load scripts-directory' path "$debugdir:$datadir/auto-load".
auto-load: Attempted file "/usr/lib/debug/usr/bin/python3.6-gdb.gdb" does not exist.
auto-load: Attempted file "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.gdb" does not exist.
auto-load: Attempted file "/usr/bin/python3.6-gdb.py" does not exist.
auto-load: Expanded $-variables to "/usr/lib/debug:/usr/share/gdb/auto-load".
auto-load: Searching 'set auto-load scripts-directory' path "$debugdir:$datadir/auto-load".
auto-load: Attempted file "/usr/lib/debug/usr/bin/python3.6-gdb.py" does not exist.
auto-load: Attempted file "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.py" exists.
auto-load: Loading python script "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.py" by extension for objfile "/usr/bin/python3.6".
auto-load: Matching file "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.py" to pattern "/usr/lib/debug"
auto-load: Not matched - pattern "/usr/lib/debug".
auto-load: Matching file "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.py" to pattern "/usr/share/gdb/auto-load"
auto-load: Matched - file "/usr/share/gdb/auto-load" to pattern "/usr/share/gdb/auto-load".
auto-load: File "/usr/share/gdb/auto-load/usr/bin/python3.6-gdb.py" matches directory "/usr/share/gdb/auto-load".

The rules which GDB uses to find the script to auto-load are described here:

https://sourceware.org/gdb/current/onlinedocs/gdb/Auto_002dloading-extensions.html

In a simplified form, it takes the absolute filepath of the loaded object file after following the symlinks, appends a -gdb.(gdb|py|scm) extension to it and tries to find a file whose path begins with one of the auto-load scripts-directory directories and ends with the constructed script name.

If no such scripts could be found, check which ones are actually available on your system. It might be possible that you are trying to debug e.g. a python3 executable, which is a symlink to python3.6, while your system's GDB installation may only supply GDB scripts for python3.5 executable. Because of the way the script names are constructed, the name of the executable actually does matter.

Also, check whether GDB is using the appropriate script directories:

(gdb) show auto-load scripts-directory
List of directories from which to load auto-loaded scripts is $debugdir:$datadir/auto-load.

and update them if necessary. When loading an object file with auto-load debugging enabled, the following line:

auto-load: Expanded $-variables to "/usr/lib/debug:/usr/share/gdb/auto-load".

shows the expanded value of the scripts-directory.

Finally, check the value of auto-load safe path:

(gdb) show auto-load safe-path
List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.

and also update it if necessary.

BTW, chances are you do not need any extra add-auto-load-scripts-directory or add-auto-load-safe-path commands in your ~/.gdbinit file, because the default auto-load script directories and safe paths usually include $datadir/auto-load, which typically expands to /usr/share/gdb/auto-load, which is often the default location for system-wide GDB scripts where the usr/bin/python*-gdb.py files can most probably be found.

like image 105
Peter Bašista Avatar answered Sep 21 '22 20:09

Peter Bašista