2015-02-11 4 views
0

Я хочу, чтобы gdb отображал только мой код (пропустите включенные заголовки). Я борется с ошибкой сегментации, вызванной случайным образом моей многопоточной программой. В GDB я вижу это:Как правильно использовать gdb?

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7fffeffff700 (LWP 27533)] 
0x0000000000409939 in std::thread::joinable (this=0x0) at /usr/include/c++/4.9.2/thread:162 
162  { return !(_M_id == id()); } 
(gdb) bt 
#0 0x0000000000409939 in std::thread::joinable (this=0x0) at /usr/include/c++/4.9.2/thread:162 
#1 0x0000000000404562 in Finder::join_threads (this=0x7ffff0000cd0) at global_search.cpp:25 
#2 0x0000000000416ea9 in std::_Mem_fn<void (Finder::*)()>::operator()<, void>(Finder&) const (this=0x7ffff00013c0, __object=...) at /usr/include/c++/4.9.2/functional:556 
#3 0x0000000000416d1e in std::_Mem_fn<void (Finder::*)()>::operator()<Finder<>, void>(std::reference_wrapper<Finder<> >, (void&&)...) const (this=0x7ffff00013c0, __ref=...) 
    at /usr/include/c++/4.9.2/functional:585 
#4 0x00000000004166fe in std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x7ffff00013b8) 
    at /usr/include/c++/4.9.2/functional:1700 
#5 0x00000000004160eb in std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)>::operator()() (this=0x7ffff00013b8) 
    at /usr/include/c++/4.9.2/functional:1688 
#6 0x0000000000415b12 in std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)> >::_M_run() (this=0x7ffff00013a0) 
    at /usr/include/c++/4.9.2/thread:115 
#7 0x00007ffff76b4d90 in execute_native_thread_routine() from /usr/lib/libstdc++.so.6 
#8 0x00007ffff7910374 in start_thread() from /usr/lib/libpthread.so.0 
#9 0x00007ffff6e2427d in clone() from /usr/lib/libc.so.6 

В какой момент в моем коде (не в библиотеке потоков) произошла ошибка? Или, по крайней мере, какой вызов функции thread :: joinable() вызвал ошибку? Можно ли получить такую ​​информацию? Мне жаль, что я задавал такие вопросы, но я совершенно не разбираюсь в отладке с помощью gdb.

ответ

1

Самый внутренний (активный) стек кадра - это кадр # 0, номер вызывающего абонента - 1 и т. Д. Глядя сверху вниз, я замечаю, что кадр # 0 находится в функции внутри пространства имен std и ссылается на файл заголовка системы как исходный код, но уже в кадре # 1 упоминается метод в классе с именем Finder, который не предоставляется стандартная библиотека, а также путь к исходному коду не относится к системному заголовку. Также быстрый google не дает результатов, указывающих, что класс Finder является частью известной структуры, поэтому, скорее всего, это ваш код.

Finder::join_threads звонки соединяются по указателю std :: thread, который равен nullptr (aka NULL) в строке 25 global_search.cpp.

1

Здесь два случая.

Один случай - один в вашем вопросе - касается следов стека. В этом случае просто невозможно устранить рамки, выходящие из вашей программы. Я предполагаю, что gdb можно научить делать это как-то, скажем, с помощью фильтра кадров, но на практике это будет путать, поскольку тогда отладчик будет представлять фальсифицированное представление текущего состояния программы, которую вы отлаживаете.

В этом случае я обычно просто использовать команду «вверх», чтобы идти вверх по стеку, пока я не вижу что-то я заинтересован в.

Другое дело вмешалась. В этом случае gdb предоставляет команду «skip», которая инструктирует ее не делать одноэтапного действия на определенные биты кода. Это может быть полезно для доступа к аксессуарам и внешнему коду. Обратите внимание, что это не представляет проблемы, связанные с удалением информации из трассировки стека, поскольку gdb не фальсифицирует какую-либо информацию, а просто обрабатывает «шаг» и «следующий» как сокращение для более длительных операций.

Смежные вопросы