无法在gdb中找到.bss部分中定义的变量名称

Yic*_*hen 4 assembly gdb gnu-assembler elf debug-symbols

我正在尝试一个简单的汇编代码:

.section .data
output:
    .ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"
.section .bss
    .lcomm buffer, 12
.section .text
.code32
.globl _start
_start:
    movl $0, %eax
    cpuid
    movl $output, %edi
Run Code Online (Sandbox Code Playgroud)

在.bss部分我定义了一个名为"buffer"的变量

当我尝试在gdb中获取其地址/值时,它只是打印:

(gdb) p $buffer
$1 = void

使用objdump,我发现该名称不在ELF文件中,那么如何在运行as和ld时保留这些名称信息?谢谢!

Pet*_*des 5

使用objdump,我发现该名称不在ELF文件中

适用于Arch Linux的GNU binutils 2.28.0-3.也许您在链接后剥离了二进制文件?

$ gcc -Wall -m32 -nostdlib gas-symbols.S
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=d5fdff41cc52e9de3b4cdae34cf4129de2b4a69f, not stripped

$ nm a.out 
080490ee B __bss_start
080490f0 b buffer           ### local symbol in the bss
080490ee D _edata
080490fc B _end
080490c4 d output
080480b8 T _start
Run Code Online (Sandbox Code Playgroud)

我不需要-g在可执行文件中保留符号.而且,在我的系统上,-static默认为-nostdlib.这并非总是如此,看到这个问答有关构建ASM源成32位或64位的静态或动态二进制文件,用gcc或与asld直接.或者与NASM和ld.

(请注意,.code32不改变目标文件格式,你需要使用编译选项,所以它可能会更好省略.code32这样你就更有可能得到错误(例如,从push %ebx),如果你尝试建立32位代码为64位对象文件.)

使用asld直接(gcc在幕后使用gcc -v,看看如何),我也得到相同的结果.

$ as gas-symbols.S -o gas-symbols.o  --32 && 
  ld -o a.out gas-symbols.o  -m elf_i386
$ nm a.out 
...
080490b0 b buffer        ## Still there
...
Run Code Online (Sandbox Code Playgroud)

在GDB中,正如Jester指出的那样,打印地址而不是值.GDB不知道它是一个数组,因为你没有使用任何指令来创建调试信息.(我不建议尝试手工编写这样的指令.例如,查看gcc -S发出的内容static char foo[100];(在文件中).

无论如何,如果您正确使用它,GDB会起作用:

$ gdb ./a.out
(gdb) b _start
(gdb) r
Starting program: /home/peter/src/SO/a.out

Breakpoint 1, _start () at gas-symbols.S:10
(gdb) p buffer
$1 = 0
(gdb) p &buffer
$2 = (<data variable, no debug info> *) 0x80490f0 <buffer>
(gdb) ptype buffer
type = <data variable, no debug info>
Run Code Online (Sandbox Code Playgroud)

您可以通过强制转换或使用x命令来解决缺少类型信息的问题:

(gdb) p (char[12])buffer
$4 = '\000' <repeats 11 times>
(gdb) p /x (char[12])buffer
$5 = {0x0 <repeats 12 times>}
(gdb) x /4w &buffer             # eXamine the memory as 4 "words" (32-bit).  
0x80490f0 <buffer>:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) help x   # read this to learn about options for dumping memory
Run Code Online (Sandbox Code Playgroud)

对于调试asm,我在我的~/.gdbinit:

set disassembly-flavor intel
layout reg
set print static-members off
Run Code Online (Sandbox Code Playgroud)

但是既然你用AT&T语法编写,你可能不希望英特尔风格的反汇编. layout asm/ layout reg虽然很棒.另请参阅标记wiki 末尾的调试技巧.标签维基充满了文档和指南的链接.