Следующая команда GDB выполняет переход назад ко всем объектам, размещенным в стеке, в конце области видимости.

Когда у меня есть выделенные в стеке объекты в области (набор команд в фигурных скобках) и я использую next в конце этой области, gdb возвращается туда, где находится каждый из выделенных в стеке объектов, в обратном порядке.

Это беспокоит во время ритуала отладки: когда имеется много экземпляров объектов, выделенных в стеке, отладчик переходит назад к каждому из них, и только когда он завершен, он переходит вперед. Вместо этого я ожидаю, что он перейдет к следующей строке после области.

Есть ли способ настроить gdb, чтобы этого не делать, или это какой-то флаг, который мне нужно передать gcc при сборке?

Сначала я подумал, что компилирую с использованием -O0 или чего-то подобного (GDB переходит к неправильным строкам не по порядку ), но здесь это не так.

Вот как я строю:

/opt/rh/devtoolset-6/root/usr/bin/c++  -MD -DDEBUG -g -ggdb -gstabs+  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type   main.cpp -c -o main.o
/opt/rh/devtoolset-6/root/usr/bin/c++  -MD -DDEBUG -g -ggdb -gstabs+  -fPIC  -Wall -Werror -Wsynth -Wno-comment -Wreturn-type   main.o -L. -L/opt/rh/devtoolset-6/root/usr/lib64 -lstdc++  -o main.exe   

Ниже то, что я вижу в отладчике. Обратите внимание на используемую версию GDB:

bash-4.2$ gdb main.exe
GNU gdb (GDB) Red Hat Enterprise Linux 7.12.1-48.el6
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main.exe...done.
(gdb) b main
Breakpoint 1 at 0x400a27: file main.cpp, line 45.
(gdb) r
Starting program: /home/brentg/scratch_sandboxes/cxxminimal/main.exe 
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64

Breakpoint 1, main (argc=1, argv=0x7fffffffeb38, envp=0x7fffffffeb48)
    at main.cpp:45
45    std::cout << __FILE__ << ":" << __LINE__ << ":" << "main begin" << std::endl;
Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-17.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64
(gdb) l
40    std::cout << __FILE__ << ":" << __LINE__ << ":" << "printing some info 2" << std::endl;
41  }
42  
43  int main(int argc, char *argv[], char *const envp[])
44  {
45    std::cout << __FILE__ << ":" << __LINE__ << ":" << "main begin" << std::endl;
46    some_function_that_uses_Foo();
47    std::cout << __FILE__ << ":" << __LINE__ << ":" << "main end" << std::endl;
48    return 0;
49  } // end main
(gdb) n
main.cpp:45:main begin
46    some_function_that_uses_Foo();
(gdb) s
some_function_that_uses_Foo () at main.cpp:38
38    std::cout << __FILE__ << ":" << __LINE__ << ":" << "printing some info 1" << std::endl;
(gdb) n
main.cpp:38:printing some info 1
39    Foo the_foo1;
(gdb) n
40    std::cout << __FILE__ << ":" << __LINE__ << ":" << "printing some info 2" << std::endl;
(gdb) l
35  
36  void some_function_that_uses_Foo()
37  {
38    std::cout << __FILE__ << ":" << __LINE__ << ":" << "printing some info 1" << std::endl;
39    Foo the_foo1;
40    std::cout << __FILE__ << ":" << __LINE__ << ":" << "printing some info 2" << std::endl;
41  }
42  
43  int main(int argc, char *argv[], char *const envp[])
44  {
(gdb) n
main.cpp:40:printing some info 2
39    Foo the_foo1;

В этот момент я задаюсь вопросом: почему я снова на линии 39? Когда я был в строке 40, входя в «следующий», то он, казалось бы, прыгает назад.

Глядя на руководство gdb для команды «следующая», я ничего не вижу в отношении конструкторов/деструкторов С++.


person bgoodr    schedule 17.09.2018    source источник
comment
Я сталкиваюсь с проблемой, о которой вы говорили, каждый день, потому что gdb будет переходить к деструктору ваших локальных объектов. Я думаю, что это сделано по замыслу, в списке рассылки gdb много дискуссий по этому поводу.   -  person ollydbg23    schedule 21.09.2018
comment
@ollydbg23 Спасибо. Я искал и нашел sourceware.org/ml/gdb/2011-10/msg00214. html, что означает, что GCC несет ответственность за выдачу отладочной информации, которую GDB может использовать, чтобы определить, где остановиться. Это действительно еще не ответ для меня, но это может помочь в получении ответа.   -  person bgoodr    schedule 01.10.2018
comment
gcc.gnu.org/bugzilla/show_bug.cgi?id=49951# c21 — последний комментарий к этой ошибке от 03 февраля 2015 г., 01:04:40 UTC. Это до сих пор не исправлено, и сейчас это глубоко в 2018 году.   -  person bgoodr    schedule 01.10.2018
comment
Ага, этот комментатор по имени asmwarrior — это я. Я действительно забыл, что это ошибка GDB или ошибка GCC, надеюсь, мы сможем пропинговать этот отчет об ошибке, и некоторые разработчики смогут решить эту проблему.   -  person ollydbg23    schedule 02.10.2018


Ответы (1)


/opt/rh/devtoolset-6/root/usr/bin/c++ -MD -DDEBUG -g -ggdb -gstabs+ ...

Вы можете страдать от нанесенных себе ран.

формат отладки STABS является устаревшим, и его не следует использовать ни в одной системе старше 15 лет. . Кроме того, он полностью неадекватен и совершенно не проверен.

libgcc-4.4.7-17.el6.x86_64

Вы также используете старый GCC-4.4.7, который был выпущен в марте 2012 года. Скорее всего, вы получите лучший опыт отладки, используя более современную версию.

person Employed Russian    schedule 18.09.2018
comment
Во-первых, это хороший совет, не используйте уколы. Во-вторых, такое пошаговое поведение будет иметь место и с DWARF, потому что gcc сообщает gdb, чтобы он вошел в деструкторы. Я не думаю, что есть флаг, чтобы отключить это. Возможно, вы можете использовать команду skip. - person Tom Tromey; 18.09.2018
comment
После дальнейших исследований я пришел к выводу, что это ошибка, которую еще предстоит исправить. См. комментарий по адресу stackoverflow.com/questions/52360140/ - person bgoodr; 01.10.2018
comment
Я вернулся и изучил реальную версию GCC, которую я использую, и она показывает С++ (GCC) 6.2.1 20160916 (Red Hat 6.2.1-3), а не древнюю версию GCC-4.4.7, как указано в этом ответе. . - person bgoodr; 01.10.2018
comment
Кроме того, я попытался использовать сборку с использованием вышеуказанного компилятора GCC 6.2.1, но с параметром -gsplit-dwarf (gcc.gnu .org/wiki/DebugFission) и обнаруживает ту же проблему. - person bgoodr; 01.10.2018