起動オプション†
section | option | description | remark |
Select Files | --file <file> | 実行形式ファイルとして <file> を指定 | |
-c, --core=<file> | core ファイルとして <file> を指定 | |
batch | --batch | バッチ処理モードで起動。 | |
remote debug | -n, --attach-name <name> | attach する process を指定する | |
-p, --attach-pid <pid> | attach する process の pid を指定する | |
core file から bcaktrace を見る†
- プログラムが SIGSEGV などのシグナルで死んだ場合に、吐き出された core ファイルを使って、落ちた箇所の特定をする
- プログラムを実行し、コアダンプが発生する
$ ./TestProg
CATest::SetEventQueue: [event_queue:0x7ffdf43294e0]
Push: [queue_num:01][EVENT_ID:RUN]
Pop(2): [queue_num:00][EVENT_ID:01:RUN]
Push: [queue_num:01][EVENT_ID:INVALID]
Pop(2): [queue_num:00][EVENT_ID:04:INVALID]
Trace/breakpoint trap (コアダンプ)
- lldb を起動。プロンプト "(lldb)" が表示される。
$ lldb ./OOO -c core
(lldb) target create "./OOO" --core "core"
Core file '/home/kazu/work/devel/c++/SIGSEGV/core' (x86_64) was loaded.
- backtrace を表示させる
$ lldb ./OOO -c core
(lldb) target create "./OOO" --core "core"
Core file '/home/kazu/work/devel/c++/SIGSEGV/core' (x86_64) was loaded.
(lldb) bt
* thread #1, name = 'OOO', stop reason = signal SIGQUIT
* frame #0: 0x00007fe7e24a5fe1 libpthread.so.0`raise(sig=<unavailable>) at raise.c:51:1
frame #1: 0x000055d2dee7c20b OOO`SigsegvOnInvalid(unsigned int) [inlined] ExecuteInvalid(sig=<unavailable>) at SigsegvWorkerThread.cpp:40:41
frame #2: 0x000055d2dee7c206 OOO`SigsegvOnInvalid(random_seed=<unavailable>) at SigsegvWorkerThread.cpp:46
frame #3: 0x000055d2dee7c3b2 OOO`SigsegvWorkerThread(p_args=<unavailable>) at SigsegvWorkerThread.cpp:85:33
frame #4: 0x000055d2dee7c0a8 OOO`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> > >::_M_run() [inlined] void std::__invoke_impl<void, void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*>((null)=<unavailable>, __f=<unavailable>, (null)=<unavailable>)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*&&) at invoke.h:60:36
frame #5: 0x000055d2dee7c0a1 OOO`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> > >::_M_run() [inlined] std::__invoke_result<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*>::type std::__invoke<void ((null)=<unavailable>, __fn=<unavailable>)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*>(void (*&&)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*&&) at invoke.h:95
frame #6: 0x000055d2dee7c0a1 OOO`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> > >::_M_run() [inlined] void std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> >::_M_invoke<0ul, 1ul>((null)=<unavailable>, this=<unavailable>) at thread:264
frame #7: 0x000055d2dee7c0a1 OOO`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> > >::_M_run() [inlined] std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> >::operator(this=<unavailable>)() at thread:271
frame #8: 0x000055d2dee7c0a1 OOO`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(CSigsegvWorkerThreadArgs*), CSigsegvWorkerThreadArgs*> > >::_M_run(this=<unavailable>) at thread:215
frame #9: 0x00007fe7e259ded0 libstdc++.so.6`___lldb_unnamed_symbol586$$libstdc++.so.6 + 16
frame #10: 0x00007fe7e249aea7 libpthread.so.0`start_thread(arg=<unavailable>) at pthread_create.c:477:8
frame #11: 0x00007fe7e23baa2f libc.so.6`__clone at clone.S:95
debug 実行†
コマンド†
アドレス
- run [arg...]
- プログラムのデバッグ実行開始
- 引数をつけると、それがそのままプログラムに渡される。
- step, s
- 次の行を実行
- その行に関数が含まれている場合は、関数の中で step 実行する。
- stepi, si
- 次の行を実行
- 次の行が関数呼び出しである場合、その関数を実行して抜けた直後で止まる。(即ち、その関数の中では止まらない)
- next, n
- 次を実行
- その行に関数が含まれている場合は、関数を全て 1 step で実行する。
- continue
- 次の breakpoint まで実行する。もし次の breakpoint がない場合、プログラムの最後まで実行する。
- print, p <variable>
- プログラム中の変数 <variable> の値を表示する。
- print <format>, <variable> [,<variable2> [, ...]]
- info
- 各種情報の表示
- info breakpoints: 現在設定されている breakpoint の一覧
- info locals : ローカル変数の一覧
- info thread(s) : スレッドの一覧
- gui
- gdb の起動オプション -tui と同様のもの(但し画面構成は異なる)で、端末内でグラフィカルに画面表示する。
- gui では、[F1][F2][F3][F4][F5][F6] [←][→] キーでメニューが表示される。
- MATE-terminal では [F1] がヘルプに取られているので、左右キーから入る必要がある。
- gui モードを抜けるには、[F1] 押しでメニューから "Exit" を選択する。(lldb自体はこれでは終了しない)
break point の保存・読み出し†
- save
- save breakpoints <file-name> : 設定した breakpoint を <file-name> に保存する
- save gdb-index
- save tracepoints
- source
- save コマンドで保存したファイルを読み込む
- source <file-name> : <file-name> を読み込む。
無反応になったプログラムの状態を調べる†
- 現在の状態を調べるため、現在の状態を core に吐かせて終了させる
$ kill -ABRT <PID>
または
$ kill -6 <PID>
- 出力された core を解析すると、上記 kill でシグナルを送られたときの状態を確認できる。
マルチスレッドプログラムの解析†
- info thread
- スレッドの一覧を表示。core の解析時にも使える
- 現在選択されているスレッドのエントリの左端に "*" が表示される。
- thread <ThreadID>
- 選択中のbacktrace (bt), frame, info などのコマンドを普通に使って解析することが出来る。
batch 処理†
フロントエンド†
core file†
- core file が出力されない場合は、 ulimit コマンドでユーザリソースの設定を変更する(bashの場合)
- まずは確認
$ ulimit -c
0
- 設定する
- ${HOME}/.bashrc に以下を記述
ulimit -c unlimited
- core のサイズを制限したければ、 "unlimited" の代わりにブロックサイズ値を指定することが出来る。しかしその場合、core の情報がその上限値によって制限され、gdb での debug 時に支障をきたす可能性がある。
参考リンク†