4

I'd like to pass some command line arguments to a python script run via gdb command, but importing the gdb module in python removes the argv attribute from sys. How do I access arg1 and arg2 within my python script shown in my example?

Command line execution:

$ gdb -x a.py --args python -arg1 -arg2

a.py:

#!/usr/bin/env python
import gdb
import sys
print('The args are: {0}'.format(sys.argv))
gdb.execute('quit')

Error raised:

AttributeError: 'module' object has no attribute 'argv'

Versions:

  • GNU gdb (GDB) 7.2
  • Python 2.6.6

Edit:

The end target I'll be debugging is a C executable that is already running, so I'll be attaching to it later in the script, so gdb -x a.py --args python -arg1 -arg2 is not correct either since the python part prints a gdb error: Reading symbols from /usr/bin/python...(no debugging symbols found)...done....

  • You might find something helpful in https://docs.python.org/3/library/argparse.html or its equivalent in 2 if you're using that. – Adam Borgo May 01 '15 at 20:40
  • @AdamBorgo argparse was added in Python version 2.7 and I'm using 2.6, however I had tried using optparse originally but it relies on sys.argv. So I boiled all that down to this simplified question actually. Thanks for your suggestion though (maybe argparse it *would* work, just not in this application)! –  May 01 '15 at 21:22
  • This isn't exactly what you want, but: If you can make `a.py` define a python function, say `a`, then you can give gdb an argument such as `-ex "python a('the answer is ',42)"`. – Mark Plotnick May 03 '15 at 01:02
  • @MarkPlotnick your answer is the closest I've come to a solution. What I don't like is its kludginess, I was hoping there would be a more straightforward method. This does work, and thank you, but maybe the answer is it cannot be done? `$ gdb -ex "python import os,sys; sys.path.append(os.getcwd()); from a import *; main('arg1', 'arg2')"`. My best idea is to write a helper bash script that launches a.py (what I'm already doing), but redirects the command line arguments to a temp file that the a.py script reads from <- this is less kludgy especially with tricky arguments and can use optparse.. –  May 04 '15 at 17:12

2 Answers2

8

-ex py

This is a possibility:

argv.py

print(arg0)
print(arg1)

Invocation:

gdb --batch -ex 'py arg0 = 12;arg1 = 3.4' -x argv.py

or equivalently:

gdb --batch -ex 'py arg0 = 12' -ex 'py arg1 = 3.4' -x argv.py

Output:

12
3.4

Then you could wrap that in the following script:

#!/usr/bin/env bash

doc="
Pass parameters to python script.

Usage:

  $0 scrpit.py 1 2

Where scrpit.py uses the arguments like:

  print(arg0)
  print(arg1)
"

py="$1"
shift
cli=''
i=0
for arg in $*; do
  cli="$cli -ex 'py arg$i = $arg'"
  i=$(($i+1))
done
eval gdb --batch $cli -x "$py"

Tested on Python 3.8.6, GDB 9.2, Ubuntu 20.10.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
3

It's not totally clear to me what you are trying to do.

An invocation of the form:

gdb --args something arg arg

Tells gdb to use something as the program to be debugged, with arg arg as the initial command-line arguments for the run command. You can inspect these inside gdb with show args.

So, your command is saying "I want to debug the python executable, passing it some arguments".

However, later you say you plan to attach to some already-running executable.

So, I think you're probably trying to script gdb in Python -- not debug the python executable.

The good news is, this is possible, just not the way you've written it. Instead you have a couple choices:

  • Make a .py file holding your script and tell gdb to source it, e.g., with gdb -x myscript.py (which you've already done...)

  • Use -ex to invoke some Python explicitly, like -ex 'python print 23'.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
  • Your first suggestion is what I would like to accomplish: `$ gdb -x a.py`, but I need to send command line arguments TO this a.py script. The a.py script eventually attaches to a C program running in the background (unimportant). I don't want to just start gdb `$ gdb` then use the `r` command later which is what using `args` seems to assume because it needs the program name `something` as its initial argument. –  May 04 '15 at 17:06
  • 1
    Write a wrapper script that takes your arguments, generates a Python file, and then invokes gdb appropriately. – Tom Tromey May 04 '15 at 17:26