在Python程序运行时获取全局变量

2 投票
2 回答
2100 浏览
提问于 2025-04-16 13:42

我在 CentOS 5.5 上写了一个 Python 2.5 的命令行程序,这个程序已经运行了一天了,现在我想结束这个程序,但又想获取一个全局变量的值。

我在网上查了一下,似乎获取全局变量值的唯一方法是把这个 Python 程序连接到 GDB 上。

假设这个全局变量是一个列表,名字叫 resultlist,我该怎么获取它的值呢?

2 个回答

0

我觉得名字对你帮助不大。因为你没有设置任何打印机制,而且你的程序已经在运行了,所以你现在基本上没什么办法了。

如果你对这些值有个大概念,最好的办法就是用一个进程内存扫描工具,开始试试看。不过我估计你成功的机会非常小,抱歉。

6

这件事情是可以做到的,但非常复杂,一不小心就可能导致程序崩溃(或者进入一种不确定的状态)。

你可以使用C语言的一个函数 PyEval_GetGlobals() 来获取全局变量的字典(就像在Python中调用 globals() 一样),然后用 PyObject_Print() 将这个对象打印到一个文件里(最简单的方式就是打印到 stdout 连接的地方)。

你需要运行GDB并将其附加到Python实例上。然后在你知道会被调用的函数上设置一个断点(如果你的程序正在打印输出,那么 PyObject_Print() 就可以用;否则可以参考这个页面,上面有一些可能会经常被调用的函数)。当程序到达断点时,你需要禁用它,然后打印全局变量。

举个例子,如果我的Python程序的进程ID是15847:

(gdb) attach 15847
Attaching to process 15847.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............. done
0x00007fff870b5e52 in select$DARWIN_EXTSN ()
(gdb) break PyObject_Print
Breakpoint 1 at 0x10003d8f4
(gdb) c
Continuing.

下次你的程序打印内容时:

Breakpoint 1, 0x000000010003d8f4 in PyObject_Print ()
(gdb) disable
(gdb) call (int)PyObject_Print((void*)PyEval_GetGlobals())
$1 = 0
(gdb) c
Continuing.

那么在你的程序输出中,你就能看到全局变量的字典了。

撰写回答