У меня проблемы с отладкой (перешагиванием) в c ++ с помощью gdb. У меня есть собственный rtos, работающий на цели powerp c e500m c. Версии программного обеспечения: g cc 4.9.2, gdb-server 5 ~ (не знаю точную версию), gdb 7.9.1 также пробовал 8.3.1. Исходный файл, скомпилированный с параметрами -g и -O0 Проблема, похоже, возникает в c ++ после перехода через функцию, если в следующих строках нет перехода, инструкция перехода на определенную величину, GDB потерял дорожку, где останавливаться при возврате функции и продолжай бежать. Я пробовал тот же код на целевой версии x86-64, он работает, как и ожидалось, без каких-либо проблем. Первым делом проверил целевую часть портирования gdb-сервера, затем зарегистрировал обмен сообщениями между хостом и целью. Как вы можете видеть ниже, проблема, кажется, находится на стороне GDB, так как GDB сам решает, где поставить точку останова.
В примере кода используется ошибка, я также добавил файл журнала. Строки, начинающиеся с "gdb:" - это сообщения от gdb к цели. Я не включаю ответы gdb-сервера, чтобы избежать путаницы. Другие строки печатаются по цели. <..> комментарии, добавленные мной позже, рассказывают о значении кода, данных или адреса, а также о том, что я делал в то время. Я также включил связанную часть файла эльфа, чтобы сделать его более понятным.
Вот что происходит. Сначала я загружаю свою программу в целевой режим с отключенным автоматическим запуском. Программа находится в памяти и ожидает запуска моей команды. Тогда я присоединяюсь к процессу для отладки. GDB вступает во владение и начинает общение, после некоторого рукопожатия и запросов ловит процесс. Он не работал, поэтому он зацикливается на самом начале кода инициализации перед основной функцией @ 210106e8. Итак, GDB знает, что я хочу остановиться на своем коде (main), ставит точку останова в первой инструкции main после операций со стеком функций @ 21010250. Затем программы запускаются по цели и ловят исключение ловушки в точке останова. Когда выполнение останавливается, GDB удаляет точку останова (инструкцию trap) и возвращает исходную инструкцию.
Позже я делаю шаг, который является строкой int i = 0. GDB устанавливает режим трассировки и запускает выполнение. Программа перехватывает исключение трассировки после выполнения первой инструкции. Поскольку я не в режиме пошагового выполнения инструкций, GDB начинает выполнение снова, пока строка c не завершится, GDB перехватит второе исключение трассировки и достигнет конца c наборов строк режима трассировки.
Теперь мы находимся на линии вызова функции и перешагнуть снова. GDB устанавливает режим трассировки и начинает выполнение программы. Программа вызывает функцию и перехватывает исключение трассировки. Gdb видит, что это не та функция (main), которая нас интересует, поскольку мы переходим, устанавливаем точку останова для точки возврата функции. Программа начинает выполнение, печатает сообщение и возвращает функцию и достигает точки останова @ 2101025 c. Все идет нормально.
Здесь он должен был остановиться, так как моя начальная команда, которая переходит к вызову функции, завершена, но продолжается.
Теперь, как вы можете видеть в выводе журнала, GDB начинает запросы о блоке кода , что он делал раньше, но не с гораздо большим числом, ожидая 52 инструкции впереди (которые все i ++). Gdb удаляет точку останова, включает режим трассировки и выполняет первую инструкцию команды i ++. После выполнения первого вмешательства и отлова исключения снова 52 запроса команд. После всего этого GDB должен установить режим трассировки и начать выполнение. Вместо этого он ставит точку останова перед текущим значением p c по адресу только что выполненной инструкции. При отключенном режиме трассировки, когда начинается выполнение, программа выполняется до завершения, так как точка останова не будет достигнута.
Если я уменьшу количество i ++ до точки, где в 52 запросе инструкции gdb увидит некоторый скачок или ветвь, все работает как положено.
И если тот же код скомпилирован как c, а не c ++, снова все работает как положено.
Как я упоминал ранее, один и тот же код работает на цели x86, все работает как положено.
код:
#include <iostream>
using namespace std;
void printHello(void)
{
cout << "Hello World" << endl;
}
int main()
{
int i = 0;
printHello();
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
return 0;
}
вывод терминала:
<attach to process>
gdb:qSupported:multiprocess+;qRelocInsn+
gdb:!
gdb:Hgp0.0
gdb:QNonStop:0
gdb:qTStatus
gdb:?
gdb:qXfer:osdata:read:processes:0,35b
gdb:qXfer:threads:read::0,35b
gdb:vAttach;10000
stopping 65537 @210106e8 <_posix_lib_process_start>
gdb:qC
gdb:Hgp10000.10001
gdb:g
gdb:qSymbol::
gdb:m21010250,4 <main>
gdb:m21010250,4
gdb:m21010250,4
gdb:m210151c8,4 <_ZSt9terminatev>
gdb:m2102e288,4 <_Unwind_DebugHook>
gdb:qXfer:threads:read::0,763
gdb:qXfer:osdata:read:processes:0,763
gdb:qXfer:threads:read::0,763
gdb:Z0,21010250,4
gdb:m21010250,4 <backup>
gdb:X21010250,0:
gdb:X21010250,4:}] <put breakpoint @ main>
gdb:vCont?
gdb:vCont;c:p10000.-1 <cont all, breakpoint ready>
starting 65537 @210106e8
trap callback
stopping 65537 @21010250 <stop @ breakpoint>
gdb:m21010250,4
gdb:m21010254,4
gdb:m21010258,4
gdb:m2101023c,4 <main's head>
gdb:m2101023c,4
gdb:m21010240,4
gdb:m21010244,4
gdb:m21010248,4
gdb:m2101024c,4
gdb:m21441fa0,4
gdb:g
gdb:qXfer:threads:read::0,763
gdb:X21010250,4:9 <remove breakpoint>
gdb:qXfer:threads:read::0,763
gdb:qXfer:threads:read::0,763
gdb:qXfer:threads:read::0,763
<stop @ int=0 line>
<step>
gdb:m2102e288,4 <backup>
gdb:X2102e288,4:}] <??put breakpoint>
gdb:m21010250,4
gdb:vCont;s:p10000.10001;c:p10000.-1 <stop thread, set trace>
single step set
starting 65537 @21010250
trace callback <instruction complete exception>
stopping 65537 @21010254
single step reset
gdb:m21010254,4
gdb:m21010258,4
gdb:m2101023c,4
gdb:m2101023c,4
gdb:m21010240,4
gdb:m21010244,4
gdb:m21010248,4
gdb:m2101024c,4
gdb:m21010250,4
gdb:m21441fa0,4
gdb:g
gdb:m21010254,4
gdb:vCont;s:p10000.10001;c:p10000.-1 <stop thread, set trace>
single step set
starting 65537 @21010254
trace callback <instruction complete exception>
stopping 65537 @21010258
single step reset <step done, new c line>
gdb:m21010258,4
gdb:m2101023c,4
gdb:m2101023c,4
gdb:m21010240,4
gdb:m21010244,4
gdb:m21010248,4
gdb:m2101024c,4
gdb:m21010250,4
gdb:m21441fa0,4
gdb:g
gdb:qXfer:threads:read::0,763
gdb:X2102e288,4:N <??remove breakpoint>
gdb:qXfer:threads:read::0,763
gdb:qXfer:threads:read::0,763
<stop @ printHello() line>
<step>
gdb:m2102e288,4
gdb:X2102e288,4:}] <??put breakpoint>
gdb:m21010258,4
gdb:vCont;s:p10000.10001;c:p10000.-1 <stop thread, set trace>
single step set
starting 65537 @21010258
trace callback
stopping 65537 @210101e8 <printHello>
single step reset
gdb:m210101e8,4
gdb:m210101ec,4
gdb:m210101f0,4
gdb:m210101f4,4
gdb:m210101f8,4
gdb:m210101fc,4
gdb:m21010200,4
gdb:m21010204,4
gdb:m21010208,4
gdb:m2101020c,4
gdb:m210101e8,4
gdb:g
gdb:m2101023c,4
gdb:m2101023c,4
gdb:m21010240,4
gdb:m21010244,4
gdb:m21010248,4
gdb:m2101024c,4
gdb:m21010250,4
gdb:m21441fa0,4
gdb:m2101025c,4
gdb:m2101025c,4
gdb:X2101025c,4:}] <put breakpoint>
gdb:vCont;c:p10000.-1 <cont all, breakpoint ready>
starting 65537 @210101e8
Hello World
trap callback <stop @ breakpoint>
stopping 65537 @2101025c
gdb:m2101025c,4
gdb:m21010260,4
gdb:m21010264,4
gdb:m21010268,4
gdb:m2101026c,4
gdb:m21010270,4
gdb:m21010274,4
gdb:m21010278,4
gdb:m2101027c,4
gdb:m21010280,4
gdb:m21010284,4
gdb:m21010288,4
gdb:m2101028c,4
gdb:m21010290,4
gdb:m21010294,4
gdb:m21010298,4
gdb:m2101029c,4
gdb:m210102a0,4
gdb:m210102a4,4
gdb:m210102a8,4
gdb:m210102ac,4
gdb:m210102b0,4
gdb:m210102b4,4
gdb:m210102b8,4
gdb:m210102bc,4
gdb:m210102c0,4
gdb:m210102c4,4
gdb:m210102c8,4
gdb:m210102cc,4
gdb:m210102d0,4
gdb:m210102d4,4
gdb:m210102d8,4
gdb:m210102dc,4
gdb:m210102e0,4
gdb:m210102e4,4
gdb:m210102e8,4
gdb:m210102ec,4
gdb:m210102f0,4
gdb:m210102f4,4
gdb:m210102f8,4
gdb:m210102fc,4
gdb:m21010300,4
gdb:m21010304,4
gdb:m21010308,4
gdb:m2101030c,4
gdb:m21010310,4
gdb:m21010314,4
gdb:m21010318,4
gdb:m2101031c,4
gdb:m21010320,4
gdb:m21010324,4
gdb:m21010328,4
gdb:m21010258,4
gdb:g
gdb:X2101025c,4:? <remove breakpoint>
gdb:m2101025c,4
gdb:vCont;s:p10000.10001 <stop thread, trace ready><??c:-1 neden yok>
single step set
starting 65537 @2101025c
trace callback <instruction complete exception>
stopping 65537 @21010260
single step reset
gdb:m21010260,4
gdb:m21010264,4
gdb:m21010268,4
gdb:m2101026c,4
gdb:m21010270,4
gdb:m21010274,4
gdb:m21010278,4
gdb:m2101027c,4
gdb:m21010280,4
gdb:m21010284,4
gdb:m21010288,4
gdb:m2101028c,4
gdb:m21010290,4
gdb:m21010294,4
gdb:m21010298,4
gdb:m2101029c,4
gdb:m210102a0,4
gdb:m210102a4,4
gdb:m210102a8,4
gdb:m210102ac,4
gdb:m210102b0,4
gdb:m210102b4,4
gdb:m210102b8,4
gdb:m210102bc,4
gdb:m210102c0,4
gdb:m210102c4,4
gdb:m210102c8,4
gdb:m210102cc,4
gdb:m210102d0,4
gdb:m210102d4,4
gdb:m210102d8,4
gdb:m210102dc,4
gdb:m210102e0,4
gdb:m210102e4,4
gdb:m210102e8,4
gdb:m210102ec,4
gdb:m210102f0,4
gdb:m210102f4,4
gdb:m210102f8,4
gdb:m210102fc,4
gdb:m21010300,4
gdb:m21010304,4
gdb:m21010308,4
gdb:m2101030c,4
gdb:m21010310,4
gdb:m21010314,4
gdb:m21010318,4
gdb:m2101031c,4
gdb:m21010320,4
gdb:m21010324,4
gdb:m21010328,4
gdb:m2101032c,4
gdb:m2101025c,4
gdb:m21010258,4
gdb:g
gdb:m2101025c,4
gdb:X2101025c,4:}] <HATA put breakpoint>
gdb:vCont;c:p10000.-1 <cont all><HATA -1 gönderdiği için, trace yapmıyor>
starting 65537 @21010260
файл эльфа
void printHello(void)
{
210101e8: 94 21 ff f0 stwu r1,-16(r1)
210101ec: 7c 08 02 a6 mflr r0
210101f0: 90 01 00 14 stw r0,20(r1)
210101f4: 93 e1 00 0c stw r31,12(r1)
210101f8: 7c 3f 0b 78 mr r31,r1
cout << "Hello World" << endl;
210101fc: 3d 20 21 04 lis r9,8452
21010200: 38 69 01 78 addi r3,r9,376
21010204: 3d 20 21 04 lis r9,8452
21010208: 38 89 82 48 addi r4,r9,-32184
2101020c: 48 02 1f a9 bl 210321b4
21010210: 7c 69 1b 78 mr r9,r3
21010214: 7d 23 4b 78 mr r3,r9
21010218: 3d 20 21 03 lis r9,8451
2101021c: 38 89 26 ec addi r4,r9,9964
21010220: 48 02 25 45 bl 21032764
}
21010224: 39 7f 00 10 addi r11,r31,16
21010228: 80 0b 00 04 lwz r0,4(r11)
2101022c: 7c 08 03 a6 mtlr r0
21010230: 83 eb ff fc lwz r31,-4(r11)
21010234: 7d 61 5b 78 mr r1,r11
21010238: 4e 80 00 20 blr
2101023c <main>:
int main()
{
2101023c: 94 21 ff e0 stwu r1,-32(r1)
21010240: 7c 08 02 a6 mflr r0
21010244: 90 01 00 24 stw r0,36(r1)
21010248: 93 e1 00 1c stw r31,28(r1)
2101024c: 7c 3f 0b 78 mr r31,r1
int i = 0;
21010250: 39 20 00 00 li r9,0
21010254: 91 3f 00 08 stw r9,8(r31)
printHello();
21010258: 4b ff ff 91 bl 210101e8 <_Z10printHellov>
i++;
2101025c: 81 3f 00 08 lwz r9,8(r31)
21010260: 39 29 00 01 addi r9,r9,1
21010264: 91 3f 00 08 stw r9,8(r31)
i++;
21010268: 81 3f 00 08 lwz r9,8(r31)
2101026c: 39 29 00 01 addi r9,r9,1
21010270: 91 3f 00 08 stw r9,8(r31)
i++;
21010274: 81 3f 00 08 lwz r9,8(r31)
21010278: 39 29 00 01 addi r9,r9,1
2101027c: 91 3f 00 08 stw r9,8(r31)