Как я могу использовать 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, тоже.

Другие вопросы по тегам