为什么我不能在gdb中使用printf和临时struct的字符串成员

时间:2013-10-25 19:29:11

标签: c gdb

这是一个简单的程序:

#include <stdio.h>
#include <string.h>

typedef struct {
        char str[10];
} my_struct;

static my_struct s1;

int main()
{
        char *temp_str = "test";
        strcpy(s1.str, temp_str);
        printf("%s\n", s1.str);
}

这个程序按预期编译和运行,但我看到gdb的一些奇怪的行为,我不太明白。这些gdb命令是在printf行上设置断点后运行的。

(gdb) p s1.str
$5 = "test\000\000\000\000\000"
(gdb) printf "%s\n", s1.str
test
(gdb) set $tmp = s1
(gdb) printf "%s\n", $tmp.str
Attempt to take address of value not located in memory.

为什么最后一个命令不起作用?在更复杂的情况下,直接访问变量(s1.str)并不是那么干净,在这个例子中是否有任何有效的方法可以使用类似$ tmp的printf?这是使用gdb 7.2。

以下情况确实有效:

(gdb) set $tmp_str = s1.str
(gdb) printf "%s\n", $tmp_str
test

另一个兴趣点是,如果我在结构中添加一个int(在这种情况下, x - 设置为4),我可以成功地执行:

(gdb) set $tmp = s1
(gdb) printf "%d\n", $tmp.x
4

1 个答案:

答案 0 :(得分:2)

可能是因为$ tmp指向一个结构(s1),而不是char数组(s1.str),gdb对事情非常聪明,但通常会按字面意思进行处理。

set $tmp = s1

通常意味着:

set $tmp = (address of)s1

因此$ tmp只是一个指针,从技术上讲,你必须将$ tmp转换/强制转换为(struct my_struct)类型指针,从中可以引用结构内容str。

set $tmp = (struct my_struct)s1

但我认为这不会在gdb中运行(不确定,请尝试一下!)。在任何情况下:

set $tmp = s1.str
printf "%s\n", $tmp

可能会对你有用。