我可以在gdb中使用c字符串调用主机进程函数吗?

时间:2017-02-15 02:51:31

标签: python-2.7 memory gdb

PyString_InternFromString是一个带有以下声明的c函数。

PyObject *PyString_InternFromString(const char *cp)

我使用以下命令和输出在gdb中调用了此函数。

(gdb) p (char *) malloc(10)
$8 = 0xcfd020 "\210\066▒\364\177"
(gdb) call strcpy(0xcfd020, "nihao")
$9 = 13619232
(gdb) p PyString_InternFromString
$10 = {PyObject *(const char *)} 0x419158 <PyString_InternFromString>
(gdb) break PyObject_Malloc
Breakpoint 1 at 0x418004: PyObject_Malloc. (17 locations)
(gdb) p 0xcfd020
$11 = 13619232
(gdb) p (const char*)0xcfd020
$12 = 0xcfd020 "nihao"
(gdb)  p ((PyObject * (*)(const char *))0x419158)((const char *)0xcfd020)
Breakpoint 1, PyString_InternFromString (cp=0x64 <error: Cannot access    memory at address 0x64>) at ../Objects/stringobject.c:4783
4783    ../Objects/stringobject.c: No such file or directory.
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(PyString_InternFromString) will be abandoned.
 When the function is done executing, GDB will silently stop.
(gdb) bt
#0  PyString_InternFromString (cp=0x64 <error: Cannot access memory at    address 0x64>) at ../Objects/stringobject.c:4783
#1  0x00007ff489a1a0c0 in ?? ()
#2  0x7b752ef9cf7f0a00 in ?? ()
#3  0x00007ff489b1b050 in ?? ()
#4  0x0000000000000065 in ?? ()
#5  0x0000000000000000 in ?? ()
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
PyObject_Malloc (nbytes=<optimized out>) at ../Objects/obmalloc.c:882
882     ../Objects/obmalloc.c: No such file or directory.
(gdb) bt
#0  PyObject_Malloc (nbytes=<optimized out>) at ../Objects/obmalloc.c:882
#1  PyString_FromString (str=0x64 <error: Cannot access memory at address     0x64>) at ../Objects/stringobject.c:143
#2  PyString_InternFromString (cp=0x64 <error: Cannot access memory at   address 0x64>) at ../Objects/stringobject.c:4783
#3  0x00007ff489a1a0c0 in ?? ()
#4  0x7b752ef9cf7f0a00 in ?? ()
#5  0x00007ff489b1b050 in ?? ()
#6  0x0000000000000065 in ?? ()
#7  0x0000000000000000 in ?? ()
(gdb) info locals
bp = <optimized out>
pool = 0x7ff489a0a370
next = <optimized out>
size = 9607536
(gdb) info args
nbytes = <optimized out>
(gdb) f 1
#1  PyString_FromString (str=0x64 <error: Cannot access memory at address   0x64>) at ../Objects/stringobject.c:143
143     ../Objects/stringobject.c: No such file or directory.
(gdb) info locals
size = 100
op = <optimized out>
(gdb) info args
str = 0x64 <error: Cannot access memory at address 0x64>
(gdb)  p ((PyObject * (*)(const char *))0x419158)(&((const char *)0xcfd020))
Attempt to take address of value not located in memory.
(gdb) call strlen("nihaobuhoa")
$13 = 10

我无法使用 Segmentation fault 调用该函数。我们可以了解 Cannot access memory at address 0x64 导致输出错误。这让我很困惑,我给PyString_InternFromString的内容是地址const char *的{​​{1}}字符串,但在函数中更改为0xcfd020。 谁知道为什么会这样?

2 个答案:

答案 0 :(得分:0)

也许你调用你的函数的方式会给GDB隐藏太多东西。

为什么不直接调用它,而不是调用指向函数PyString_InternFromString()的指针指针?调用函数时也可以使用C字符串,GDB会自动调用malloc()来创建字符串。

(gdb) # reach a point where every initializations of your call (and
subcalls) are done. For example, main.  
(gdb) b main  
(gdb) run  
(gdb) p /x PyString_InternFromString("nihao")

注意:

  1. 这个调用隐含地依赖于它所需的一切的先前初始化,即直接或间接使用的全局对象。如果是这种情况,您应首先在此类初始化后中断并执行此调用。

  2. 从GDB调用函数至少需要首先初始化C运行时,原因与第1点中所述的原因相同。因此,当您到达main()函数时,应该执行调用。

  3. 可以调试通过GDB调用的函数(如错误消息../Objects/stringobject.c: No such file or directory.所述)。下载它和specify the directory to GDB,然后您应该能够调试它(如果这是来自您的OS发行版的库,调试信息可能是独立的)

答案 1 :(得分:0)

这是因为gdb从符号表读取错误的PyString_InternFromString地址。我将python符号表转储到纯文本文件中,发现PyString_InternFromString的真实地址与从gdb打印的地址不同。