Как я могу использовать gdb для отладки кода, собранного с помощью yasm?
У меня есть сборка кода с использованием yasm и связывание с моей программой на C++, но я не могу установить точки останова в gdb для символов из файла на языке ассемблера.
Командные строки, вероятно, не очень хорошо освещают, но здесь мы идем:
"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
Это все строит без происшествий, и программа запускается. Но когда я пытаюсь загрузить его в gdb для его отладки, я не могу поставить точки останова на какие-либо функции в файле yasm. Например, у меня есть функция MandelRect. Вот GDB, показывающий мне, откуда он вызывается, где-то в основном:
(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.
Вот GDB, показывая мне, каков его адрес:
(gdb) info address MandelRect
Symbol "MandelRect" is at 0x409980 in a file compiled without debugging.
Вот что GDB не может установить точку останова:
(gdb) break MandelRect
Function "MandelRect" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
И если я поставлю точку останова по правильному адресу, когда выполнение достигнет функции, я не смогу пройти по ней инструкцию за инструкцией. Насколько я могу (надоело сказать), он просто работает от ярлыка к ярлыку.
Очевидно - ну, может быть? - это как-то связано с требованием GDB, что файл был скомпилирован без отладки. Но в соответствующем файле.o и в двоичном файле, похоже, есть символы:
~/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
Так как мне это исправить? Я что-то не так понял или yasm -g
сломана? Кому-нибудь удалось получить отладочную информацию yasm для работы с gdb?
(Система Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 GNU/Linux
.)
1 ответ
Моя программа содержала код, который был за пределами .text
раздел, как я каким-то образом умудрился неправильно написать "текст" в файле asm (как вы можете видеть в выводе objdump выше). yasm позволяет вам называть разделы так, как вам нравится, и, очевидно, они помечаются как исполняемые, но, очевидно, многие инструменты этого не ожидают...
Это также исправило некоторые странные результаты, которые я получал от perf
, тоже.