9

I'm trying to setup a system where I can add python scripts to a directory, and the next time I load gdb they will be accessible (the point being to place this in version control and allow other engineers simple access to my helper scripts). For starters I've written a hello.py file, and when I type source /path/to/hello.py in gdb, and then type hello it works as expected.

How do I make GDB do this automatically? The documentation suggests using the data-directory, and placing scripts in data-directory/python/gdb/command. Placing my hello.py file in this directory does nothing though (however it does end up creating a hello.pyc file).

I've additionally tried adding this directory to my directory listing with dir /path/to/hello/ and then hoping to be able to type source hello.py but this also fails.

1
  • What do you mean by automatically? Do you mean to load all Python scripts in a given directory? Or current directory? Or something else? Commented Oct 19, 2015 at 10:20

5 Answers 5

11

Make a .gdbinit file, and put all your source commands in there in the same directory where you'll be starting gdb from. I believe the file will look something like this:

.gdbinit

source /path/to/hello.py
source /path/to/foobar.py
etc, etc

reference

EDIT: Including the .gdbinit file in your version control will make sure that the files are included, independent of the global gdb settings.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. That does work, but I was hoping there was something that could do this in a more automated fashion. This requires manually adding each script to the .gdbinit, plus including a full path (my attempts to source a python file without the full path result in bizarre errors). I suppose I could have a bash script that automatically generates a .gdbinit file and passes all the paths based on where the user has setup their version control, but I was hopeful the GDB designers put hooks in for something like this.
Maybe you could add the generation of .gdbinit to your Makefile? I agree, it's too bad there's not a clean way of doing it (that I know of).
I feel like I must be missing something simple. In particular the last line about the data-directory here. But having a second person unclear helped me make up a hackish solution. Thanks!
6

I was looking for an answer to the same question today. Eventually I came up with the following:

.gdbinit

python
import glob

python_dir = "/path/to/python"

# Search the python dir for all .py files, and source each
py_files = glob.glob("%s/*.py" % python_dir)
for py_file in py_files:
    gdb.execute('source %s' % py_file)
end

Note that .gdbinit can be ~/.gdbinit or ./.gdbinit; see gdbinit(5).

Comments

3

You'll need to set auto-load on using the following command:

set auto-load python-scripts on

Reference: http://sourceware.org/gdb/current/onlinedocs/gdb/Python-Auto_002dloading.html#Python-Auto_002dloading

1 Comment

I saw that, but whenever I try typing that (either in gdb, or putting it in my .gdbinit) it gives me the error: "on" or "off" expected. I think it is just calling whatever it does for "auto-load" and passing that "python-scripts".
1

It seems there must be a better way, but for now I did the following. To .gdbinit I added:source /path/to/setup_python.py

Then I wrote the file setup_python.py as:

#!/usr/bin/python
import glob
import os

# Search the python dir for all .py files, and source each
setup_dir = os.path.dirname(__file__)
python_dir = os.path.join(setup_dir, "python")
py_files = glob.glob("%s/*.py" % python_dir)

for py_file in py_files:
    gdb.execute('source %s' % py_file)

This will source all files in the python sub-directory, and both setup_python.py and those files can be checked into source control.

2 Comments

This is genius!!
Sadly, doesn't work if your files are dependent on one another.
0

Different, but similar problem: I tell everyone that in their home directory "~/.gdbinit" file they must load one common python module via an absolute path. This is exactly one line, not something complicated.

You should note: Some would call this a security threat, It is a balancing act - I have to trust my team, they have to trust me. I think of it this way: we all work with sharp-pointy things, we must be knowledgeable of what we are doing. Every team is unique, use your judgement.

I also have to deal with multiple versions of GDB but a common single .gdbinit file. Example; AndroidOLD(GDB), AndroidNEW(GDB), LinuxHost(GDB), and SomeOther(GDB)

People switch between projects using different things through out the day, common script directory problem. And I have my own scripts in my home directory

I depend upon GDB-Python extensions

import os
import gdb

On Linux, I can determine the exact version of GDB by looking at the absolute path to the executable hence: AndroidOLD(gdb) vrs AndroidNEW(gdb) can be determined by looking for a version number in the path.

exename = os.readlink( '/proc/self/exe' )

I can also use these items to determine the host type(cygwin, linux, mac, etc), and more details about the target architecture (ie: Which android cpu target?)

print (gdb.HOST_CONFIG)
# gives: x86_64-linux-gnu
# Alternates: MACOS, or CYGWIN32 or CYGWIN64
print (gdb.TARGET_CONFIG)
# Gives: 64bit android, 32bit android, or something else

Now, more to the original posters question: A common directory with lots of scripts

  1. I have multiple "common directories"
  2. And I have to deal with different architectures
  3. And my people switch between projects
  4. And switch between versions

Some project systems have a common root directory (ie: Android) for the project or module, and all sub components are sub directories of that common directory. Using python - you can start with the current directory, then climb up the directory tree one at a time until you find some magic file that tells you more (for example some file that identifies the root directory of an android build)

now that I know all of that, I can iterate over the files I need to load via:

import gdb
gdb.execute('source %s' % filename)

Problem solved.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.