使用gdb进行调试时的消息:单步执行直到退出函数_start

时间:2016-09-23 19:07:19

标签: assembly x86 gdb nasm

我正在linux上使用nasm编写汇编语言程序。问题是在使用gdb调试期间它没有进入_start函数并给出消息“单步执行直到退出函数_start”,

另外,当我在第1行之后设置断点时,它说:

(gdb) break 2  
Note: breakpoints 1 and 2 also set at pc 0x4000b0.  
Breakpoint 3 at 0x4000b0: file new3.asm, line 2.  

(gdb) break 3  
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0.  
Breakpoint 4 at 0x4000b0: file new3.asm, line 3.  

我正在使用命令组装和链接它:

nasm -g  -f elf64 new3.asm  
ld  -g new3.o

然后我使用gdb new3.out调试它。 gdb版本是7.11.1

该计划如下:

section .text  
    global _start   ;must be declared for linker (ld)   
_start:             ;tells linker entry point  
    call sum  
    mov edx,len     ;message length  
    mov ecx,msg     ;message to write  
    mov ebx,1       ;file descriptor (stdout)  
    mov eax,4       ;system call number (sys_write)  
    int 0x80        ;call kernel  
    mov eax,1       ;system call number (sys_exit)  
    int 0x80        ;call kernel  

sum:  
   mov     eax, ecx  
   add     eax, edx  
   add     eax, '0'  
   ret  
section .data  
msg db 'Hello, world!', 0xa  ;string to be printed  
len equ $ - msg     ;length of the string  

我如何进入_start进行调试,这是什么意思?

(gdb) break 3
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0.
Breakpoint 4 at 0x4000b0: file new3.asm, line 3.

1 个答案:

答案 0 :(得分:2)

使用nasm -f elf64 -F dwarf -g new3.asm制作矮人调试信息,而不是默认(stabs)。 (使用nasm -felf64 -y查看默认值)。 yasm -felf64 -gdwarf2 new3.asm也有效。 (实际上单步执行即使你遗漏-gdwarf2为yasm:我猜它默认包含足够的。)

然后gdb将能够通过源代码行单步执行,而不仅仅通过指令(stepi)。您不需要ld -g,它不会做任何事情。

您可能还应该直接与gcc -nostdlib -g new3.o链接,而不是ld。如果您向ld命令行添加了任何动态库,那么您将有一个损坏的二进制文件(因为ld的默认ELF解释器路径在现代x86-64多系统系统上没有用)。请参阅Building an executable from asm source that defines _start vs. main, static or dynamic

另外,请勿使用64位代码中的int 0x80 32位ABI。

使用stepi(或si)逐步说明而不是按来源行。

使用b *0x4000b0根据数字地址设置断点。或者使用标签名称,例如b _start在入口点设置断点。

有关使用gdb调试asm的更多提示,请参阅标记wiki的底部。

您文件中的第一条指令位于第4行,因此b 1b 4都在CALL指令上设置了断点,这就不足为奇了

b 5确实在CALL之后的指令上设置断点。即使gdb只有STABS调试信息(不是DWARF或DWARF2),这部分也能正常工作,但单步执行则不行。 IDK为什么。

(gdb) b _start
Breakpoint 1 at 0x4000b0
(gdb) b 5
Breakpoint 2 at 0x4000b5: file new3.asm, line 5.
(gdb) r
Starting program: /home/peter/src/SO/a.out

Breakpoint 1, 0x00000000004000b0 in _start ()