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
.)
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With