Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use gdb to debug code assembled using yasm?

I've got code assembling using yasm, and linking into my C++ program, but I can't set breakpoints in gdb on symbols from the assembly language file.

The command lines probably aren't terribly illuminating, but here we go:

"g++"  -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -std=c++11   -I"$HOME/usr/include" -c -o "bin/gcc-4.7/debug/main.o" "main.cpp"
yasm -g dwarf2 -f elf64 -o bin/gcc-4.7/debug/mandel.o mandel.yasm
"g++" -L"$HOME/usr/lib" -Wl,-R -Wl,"$HOME/usr/lib" -Wl,-rpath-link -Wl,"$HOME/usr/lib" -o "bin/gcc-4.7/debug/mandel" -Wl,--start-group "bin/gcc-4.7/debug/main.o" "bin/gcc-4.7/debug/mandel.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lboost_system -lboost_thread -Wl,--end-group -g 

That all builds without incident, and the program runs. But when I try to load it into gdb to debug it, I can't seem to put breakpoints on any functions in the yasm file. For example, I have a function in there called MandelRect. Here's gdb showing me where it's called from, somewhere in main:

(gdb) disassemble 0x404ada,0x404af0
Dump of assembler code from 0x404ada to 0x404af0:
   0x0000000000404ada <main()+474>:     mov    %rax,%rdi
   0x0000000000404add <main()+477>:     callq  0x409980 <MandelRect>
   0x0000000000404ae2 <main()+482>:     movq   $0x0,-0x18(%rbp)
   0x0000000000404aea <main()+490>:     jmp    0x404b1c <main()+540>
   0x0000000000404aec <main()+492>:     mov    -0x18(%rbp),%rdx
End of assembler dump.

Here's gdb showing me what its address is:

(gdb) info address MandelRect
Symbol "MandelRect" is at 0x409980 in a file compiled without debugging.

Here's gdb being unable to put a breakpoint on it:

(gdb) break MandelRect
Function "MandelRect" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n

And if I put a breakpoint at the right address, when execution reaches the function, I can't step through it instruction by instruction. It just runs from label to label, as far as I can (be bothered to) tell.

Obviously - well, maybe? - this has something to do with gdb's insistence that the file was compiled without debugging. But there do appear to be symbols in the relevant .o file and in the binary:

~/tests/mandel/bin/gcc-4.7/debug% nm mandel.o | grep MandelRectAsm
0000000000000000 R MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% nm mandel | grep MandelRectAsm 
000000000040a340 R MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% objdump -t mandel.o | grep -i MandelRectAsm
0000000000000000 g       .txt   0000000000000000 MandelRectAsm
~/tests/mandel/bin/gcc-4.7/debug% objdump -t mandel | grep -i MandelRectAsm
000000000040a340 g       .txt   0000000000000000              MandelRectAsm

So how do I fix this? Have I misunderstood something, or is yasm -g broken? Has anybody ever managed to get yasm's debug info to work with gdb?

(System is Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 GNU/Linux.)

like image 640
Tom Seddon Avatar asked Oct 26 '14 22:10

Tom Seddon


People also ask

Can you use gdb on assembly?

gdb is the GNU source-level debugger that is standard on linux (and many other unix) systems. It can be used both for programs written in high-level languages like C and C++ and for assembly code programs; this document concentrates on the latter.

How do I create assembly in gdb?

From within gdb press Ctrl x 2 and the screen will split into 3 parts. First part will show you the normal code in high level language. Second will show you the assembly equivalent and corresponding instruction Pointer . Third will present you the normal gdb prompt to enter commands.

What is assembly debugger?

The debugger automatically displays the contents of memory locations and registers as they are accessed and displays the address of the program counter. This display makes assembly debugging a valuable tool that you can use together with source debugging.


1 Answers

My program contained code that was outside the .text section, as I'd somehow managed to misspell "text" in the asm file (as you can see in the objdump output above). yasm lets you name your sections as you like, and evidently they end up marked as executable, but clearly many tools aren't expecting this...

This also fixed some odd results I was getting from perf, too.

like image 102
Tom Seddon Avatar answered Oct 10 '22 04:10

Tom Seddon