我不确定我是否误解了GDB文档中关于x
和print
命令的内容,但它似乎建议将其用作x {expr}
应该将expr
视为地址。我在程序的.data
部分中有一个标记的数据位,称为string
:
SECTION .data
string: db "KANGAROO"
如果我想检查地址为string
的内存,会发生以下情况:(gdb) x/8 string
得到:'string' has unknown type; cast it to its declared type
为什么广发行抱怨类型转换?我要求它做的就是转到内存位置string
(这显然是一个地址-如果我将string
加载到寄存器中,它看起来明显像一个偏移量)。
简单的转换,假设它希望我将string
转换为指向某些数据的指针:(gdb) x/8 (char*)string
做了一件很奇怪的事它以某种方式知道要读取string
的确切字节数(我尝试了几种不同大小的字符串),显示这些字节,但随后抱怨它试图访问string
的 value 地址的内存,而不是string
本身:0x4f4f5241474e414b: Cannot access memory at address 0x4f4f5241474e414b
其中数据0x4f4...
是字符串的ASCII码。因此,它完全跳过了string
的地址,现在将位置string
中包含的数据视为地址表达式。什么?
我哪里糊涂了?string
标签实际上不是内存地址吗?因为我本以为x
命令只是将其视为地址表达式,但似乎并非如此。它为什么要我投数据?我只想读取.data
中特定标记位置的n个字节。我错过了什么?
2条答案
按热度按时间w80xi6nr1#
GDB对
string
的所有内容都是一个符号 * 值 *。GDB不知道如何将该符号值转换为某个对象的地址。考虑以下程序:
在没有
-g
的情况下编译时,需要告诉GDB&string2
是内存中字符串的地址,而&string1
是指向字符串的指针的地址:mlmc2os52#
**使用
x /8c &string
**将内存转储到标有该符号的地址。这似乎表明它作为
x {expr}
的使用应该将expr
视为地址GDB语法很像C。如果它不知道调试信息中的类型,它会假设它是一个值类型,如C
int string
或float string
,其中裸名称计算为存储在内存中的值,而不是像char string[]
那样,在大多数上下文中使用裸名称会给你地址。当GDB没有类型时,它拒绝计算使用没有
&
地址操作符的符号的表达式。其中包括用作x
命令操作数的表达式。它不会隐式地接受符号的地址。GDB知道
string
是可执行文件的符号表中的一个符号,因此它有一个地址,但GDB只知道这些。它不知道string
应该计算符号的地址,无论它是x
还是print
的操作数。(尽管print
确实有很多内置的魔法,当GDB知道类型时。例如:
如果在C中有一个
char *ptr
变量,x ptr
使用该变量的值并检查指向的内存,转储。而不是像从x &ptr
获取的8字节指针数据本身,以检查C变量或asm符号地址处的内存。类型不是问题,它默认为32位块,转储为十六进制。这和使用p而不使用强制转换的问题是一样的。