【问题标题】:GDB question with C programC程序的GDB问题
【发布时间】:2011-08-31 13:36:31
【问题描述】:

这里我正在研究一个用 C 编写的简单程序,它将一个 char 指针保存到一个字符串中,该字符串表示“Hello, world!\n”

这是我的 GDB 的输出...我对 GDB 的不一致以及这里的内容感到困惑:

$ gcc -g pointer.c
$ gdb -q ./a.out
Reading symbols for shared libraries .. done
(gdb) list
1   #include <stdio.h>
2   #include <string.h>
3   
4   int main() {
5     char str[20];
6     char *pointer;
7   
8     strcpy(str, "Hello, world!\n");
9     pointer = str;
10    printf("%s",pointer);
(gdb) 
11  }
(gdb) break 10
Breakpoint 1 at 0x100000ed1: file pointer.c, line 10.
(gdb) run
Starting program: /Users/___/a.out 
Reading symbols for shared libraries +. done

Breakpoint 1, main () at pointer.c:10
10    printf("%s",pointer);
(gdb) print pointer
$1 = 0x7fff5fbff950 "Hello, world!\n"
(gdb) print &pointer
$2 = (char **) 0x7fff5fbff948
(gdb) x/s 0x7fff5fbff950
0x7fff5fbff950:  "Hello, world!\n"
(gdb) x/16b 0x7fff5fbff950
0x7fff5fbff950:  "Hello, world!\n"
0x7fff5fbff95f:  ""
0x7fff5fbff960:  "x??_?"
0x7fff5fbff967:  ""
0x7fff5fbff968:  "՝?Y4?K\033???_?"
0x7fff5fbff977:  ""
0x7fff5fbff978:  "?\016"
0x7fff5fbff97b:  ""
0x7fff5fbff97c:  "\001"
0x7fff5fbff97e:  ""
0x7fff5fbff97f:  ""
0x7fff5fbff980:  ""
0x7fff5fbff981:  ""
0x7fff5fbff982:  ""
0x7fff5fbff983:  ""
0x7fff5fbff984:  ""
(gdb) x/x 0x7fff5fbff950
0x7fff5fbff950: 0x48
(gdb) x/x 0x7fff5fbff951
0x7fff5fbff951: 0x65
(gdb) x/s 0x7fff5fbff951
0x7fff5fbff951:  "ello, world!\n"
(gdb) print &pointer
$3 = (char **) 0x7fff5fbff948
(gdb) x/x 0x7fff5fbff948
0x7fff5fbff948: 0x00007fff5fbff950
(gdb) x/x 0x7fff5fbff949
0x7fff5fbff949: 0x4800007fff5fbff9
(gdb) x/2x 0x00007fff5fbff950
0x7fff5fbff950: 0x77202c6f6c6c6548  0x00000a21646c726f

我的问题是:

在内存中的这些位置之一中存储了多少字节的信息?当我在地址 0x7fff5fbff950,内容似乎是 0x48(ASCII 'H')。那么这是否意味着每个内存地址只存储一个字节的信息?好的。让我们假设它确实如此。然后我在 print &pointer: 0x7fff5fbff948 给出的地址上运行相同的“x/x”命令

我得到值 0x00007fff5fbff950,我认为(忽略前导零)是内存中“Hello, world!\n”字符串的开头。

现在 0x00007fff5fbff948 怎么能包含 0x00007fff5fbff950 并且仍然只有一个字节的内存?所以我查看 0x00007fff5fbff949... 现在再次告诉我,我们每次只查看一个字节,因为我们丢失了尾随的 0x50(我知道小端序,所以也许我的措辞令人困惑)。

现在我真的很生气...我尝试执行 x/2x 0x7fff5fbff948 并遭到两个巨大的十六进制数字的攻击...

所以内存中的数据一次存储一个字节,不知何故 x/x 有时会给我每个内存一个字节,有时会给我一个完整的地址?如何控制调试器将输出什么? x/x 应该检查这个地址的内容并以十六进制输出。我可以将 x/b 用于单个字节,将 x/2b 用于 2 个字节......但是 x/2x 是什么意思?

对不起,意识流问题。希望有人能帮我解决这个问题。

【问题讨论】:

    标签: assembly gdb x86-64 x86


    【解决方案1】:

    内存是字节可寻址的,这意味着每个字节都有一个不同的地址。然后您可以解释将一对字节表示为 16 位整数,将四个字节表示为 32 位整数等。该格式说明符可以让您做到这一点 - 根据您的打印内存内容对其的解释。所以x/2x 0x7fff5fbff948 将打印两个字长(这里是 64 位)整数,第一个在地址 0x7fff5fbff948,第二个在地址 0x7fff5fbff950

    【讨论】:

    • 首先,感谢您的回复。好的,但是两个 64 位整数显然对应于两个 8 字节整数。由于每个字节都有其不同的地址,如果我执行 x/2x 并在地址 ____48 和 ____50 处打印两个 64 位整数,这意味着应该与 _____48 和 _____50 重叠,并且我在 48 的第三个字节中看不到任何重叠以及 50 的第一个字节及以后。你能帮忙解释一下吗?
    • 为什么会有重叠? 0x50 - 0x48 = 8,即八个字节。
    • :) 谢谢。愚蠢的错误......忘了我们在 16 号基地。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多