如何将参数传递给从命令行启动的Python GDB脚本

4

我希望能够通过gdb命令传递一些命令行参数给一个Python脚本,但是在Python中导入gdb模块会删除sys中的argv属性。请问如何在下面示例中的Python脚本内访问arg1和arg2?

命令行执行:

$ 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')

出现错误:

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

版本:

  • GNU gdb (GDB) 7.2
  • Python 2.6.6

编辑:

我将要调试的最终目标是一个正在运行的C可执行文件,所以我稍后会在脚本中附加到它,因此gdb -x a.py --args python -arg1 -arg2也不正确,因为python部分会打印出一个gdb错误:从 /usr/bin/python...读取符号...(没有找到调试符号)...完成。...


如果你正在使用Python 2,你可以在https://docs.python.org/2/library/argparse.html中找到类似的有用信息。 - Adam Borgo
@AdamBorgo argparse是在Python 2.7版本添加的,而我正在使用2.6版本。但是我曾尝试使用optparse,但其依赖于sys.argv。所以,我的问题可以简化为这个。感谢您的建议(也许argparse在其他应用中确实可以使用!)。 - user3407196
这不完全是你想要的,但是:如果你可以让 a.py 定义一个 Python 函数,比如说 a,那么你就可以给 gdb 传递一个参数,例如 -ex "python a('答案是',42)" - Mark Plotnick
@MarkPlotnick,你的答案是我找到的最接近解决方案。我不喜欢的是它的笨拙性,我希望有一种更直接的方法。这确实有效,谢谢你,但也许答案是不能做到?`$ gdb -ex“python import os,sys; sys.path.append(os.getcwd()); from a import *; main('arg1', 'arg2')”。我的最佳想法是编写一个辅助bash脚本来启动a.py(我已经在做了),但将命令行参数重定向到a.py脚本读取的临时文件中<-这样做不那么笨拙,特别是对于棘手的参数和可以使用optparse。 - user3407196
2个回答

8

-ex py

这是一种可能性: argv.py
print(arg0)
print(arg1)

调用:

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

或者等价地说:
gdb --batch -ex 'py arg0 = 12' -ex 'py arg1 = 3.4' -x argv.py

输出:

12
3.4

然后,您可以将其包装在以下脚本中:
#!/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"

在Python 3.8.6、GDB 9.2和Ubuntu 20.10上进行了测试。


1
你可以使用 -ex 'py arg0=arg0; arg1=arg1; ...' 声明/赋值,而不是将它们分成多个以 -ex 'py' 开头的单独语句。 - Xinyi Li
1
@XinyiLi 谢谢,已添加到答案中。突然的蟾蜍崇拜太棒了!!! - Ciro Santilli OurBigBook.com

3

我不完全明白您想要做什么。

下面是一个形式的调用:

gdb --args something arg arg

告诉 gdb 使用 something 作为被调试程序,并使用 arg arg 作为 run 命令的初始命令行参数。你可以在 gdb 中使用 show args 来检查这些参数。
所以,你的命令是在说“我想要调试 python 可执行文件,并传递一些参数。”
然而,后来你说你计划 attach 到一些已经运行的可执行文件上。
所以,我认为你可能正在尝试在 Python 中编写 gdb 脚本,而不是调试 python 可执行文件。
好消息是,这是可能的,只不过你没有按照正确的方式写。相反,你有几个选择:
  • 创建一个包含你的脚本的 .py 文件,并告诉 gdb 用 gdb -x myscript.py 来执行它(你已经这样做了...)。

  • 使用 -ex 来显式地调用一些 Python,例如 -ex 'python print 23'


您的第一个建议是我想要实现的:$ gdb -x a.py,但我需要将命令行参数发送到这个a.py脚本。a.py脚本最终会附加到后台运行的C程序(不重要)。我不想只是启动gdb $ gdb,然后稍后使用r命令,这似乎是使用args所假设的,因为它需要程序名称something作为其初始参数。 - user3407196
1
编写一个包装脚本,接受您的参数,生成一个Python文件,然后适当地调用gdb。 - Tom Tromey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接