#author("2023-05-21T09:59:11+09:00","","") #author("2023-05-21T11:26:33+09:00","","") #topicpath ///////////////////////////////////////////////////////////////////////////////// * 目次 [#v9e07999] #contents(); ///////////////////////////////////////////////////////////////////////////////// * 起動オプション [#x27cbae1] |~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 を見る [#k5459c0a] - プログラムが 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 実行 [#vb4b2254] ///////////////////////////////////////////////////////////////////////////////// ** コマンド [#zb645053] アドレス - backtrace, bt - bt, backtrace -- バックトレースを表示する -- 書式 bt [file:]function bt [file:]line - run [arg...] -- プログラムのデバッグ実行開始 -- 引数をつけると、それがそのままプログラムに渡される。 - step, s - s, step -- 次の行を実行 -- その行に関数が含まれている場合は、関数の中で step 実行する。 - stepi, si - si, stepi -- 次の行を実行 -- 次の行が関数呼び出しである場合、その関数を実行して抜けた直後で止まる。(即ち、その関数の中では止まらない) - next, n - n, next -- 次を実行 -- その行に関数が含まれている場合は、関数を全て 1 step で実行する。 - continue -- 次の breakpoint まで実行する。もし次の breakpoint がない場合、プログラムの最後まで実行する。 - print, p <variable> - p, print <variable> -- プログラム中の変数 <variable> の値を表示する。 - print <format>, <variable> [,<variable2> [, ...]] - p, print <format>, <variable> [,<variable2> [, ...]] -- プログラム内の変数を <format> に従った書式で表示する (lldb) print "[id:%d][address: %p]\n", i, address_array[i] -- ''printf'' ではなく ''print'' であることに注意! - list, l - l, list -- 現在中断している場所の周辺のプログラムコードを表示する。 -- 表示領域を指定したい場合は、引数に開始行番号と終了行番号を半角コンマで区切って渡す。 (lldb) l <start-line-no>,<end-line-no> - help - h, help -- 全コマンドとその説明を一覧表示 - info -- 各種情報の表示 -- info breakpoints: 現在設定されている breakpoint の一覧 -- info locals : ローカル変数の一覧 -- info thread(s) : スレッドの一覧 - t, thread <thread-id> -- thread ID を指定する - f, frame <frame-id> -- frame を指定する - gui -- gdb の起動オプション -tui と同様のもの(但し画面構成は異なる)で、端末内でグラフィカルに画面表示する。 -- gui では、[F1][F2][F3][F4][F5][F6] [←][→] キーでメニューが表示される。 -- MATE-terminal では [F1] がヘルプに取られているので、左右キーから入る必要がある。 -- MATE-terminal では [F1] がヘルプに取られているので、[F2],[F6] 等を押して他メニューをプルダウンさせてから左右キーで入る必要がある。 -- gui モードを抜けるには、[F1] 押しでメニューから "Exit" を選択する。(lldb自体はこれでは終了しない) //=============================================================================== ** break point の保存・読み出し [#a0673309] - save -- save breakpoints <file-name> : 設定した breakpoint を <file-name> に保存する -- save gdb-index -- save tracepoints - source -- save コマンドで保存したファイルを読み込む -- source <file-name> : <file-name> を読み込む。 ///////////////////////////////////////////////////////////////////////////////// * 無反応になったプログラムの状態を調べる [#laf4d12e] + 現在の状態を調べるため、現在の状態を core に吐かせて終了させる $ kill -ABRT <PID> または~ $ kill -6 <PID> + 出力された core を解析すると、上記 kill でシグナルを送られたときの状態を確認できる。 ///////////////////////////////////////////////////////////////////////////////// * マルチスレッドプログラムの解析 [#s60efb84] - info thread -- スレッドの一覧を表示。core の解析時にも使える -- 現在選択されているスレッドのエントリの左端に "*" が表示される。 - thread <ThreadID> -- 解析したい スレッドを選択する - 選択中のbacktrace (bt), frame, info などのコマンドを普通に使って解析することが出来る。 ///////////////////////////////////////////////////////////////////////////////// * batch 処理 [#h8b29af9] ///////////////////////////////////////////////////////////////////////////////// * フロントエンド [#ha9e3fe9] ///////////////////////////////////////////////////////////////////////////////// * core file [#o08f3209] - core file が出力されない場合は、 ulimit コマンドでユーザリソースの設定を変更する(bashの場合) - まずは確認 $ ulimit -c 0 - 設定する -- ${HOME}/.bashrc に以下を記述 ulimit -c unlimited -- core のサイズを制限したければ、 "unlimited" の代わりにブロックサイズ値を指定することが出来る。しかしその場合、core の情報がその上限値によって制限され、gdb での debug 時に支障をきたす可能性がある。 ///////////////////////////////////////////////////////////////////////////////// * 参考リンク [#links] - [[lldb で使えるコマンド一覧 - yokaze.github.io>https://yokaze.github.io/2018/01/06/]]