作成中のC++プログラムをデバッグしようとしていますが、LLDBで実行してプログラムを停止すると、元のソースではなく、アセンブラのみが表示されます。例えばクラッシュ後、デバッグしようとしています:
_Process 86122 stopped
* thread #13: tid = 0x142181, 0x0000000100006ec1 debug_build`game::update() + 10961, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000100006ec1 debug_build`game::update() + 10961
debug_build`game::update:
-> 0x100006ec1 <+10961>: movq (%rdx), %rdx
0x100006ec4 <+10964>: movq %rax, -0xb28(%rbp)
0x100006ecb <+10971>: movq -0x1130(%rbp), %rax
0x100006ed2 <+10978>: movq 0x8(%rax), %rsi
_
_-O0 -g
_でコンパイルしています。 Xcode(OSXを使用)またはコマンドラインからデバッガーを実行するときにも同じことがわかります。
ソースコードをLLDBに表示するには、他に何が必要ですか?
追記
典型的なビルドコマンドの例を次に示します。
_clang++ -std=c++1y -stdlib=libc++ -fexceptions -I/usr/local/include -c -O2 -Wall -ferror-limit=5 -g -O0 -ftrapv lib/format.cpp -o format.o
_
以前の_-O2
_は、それが私が使用しているデフォルトだからですが、後の_-O0
_がそれをオーバーライドすると思いますよね?
私が試したこと
同じビルド設定を使用する単純な「hello world」プログラムでこの問題を再現しました。
いくつか検索した後、warning: no debug symbols in executable (-Arch x86_64)
と表示された_dsymutil main.o
_を実行してみたので、ビルドコマンドによってデバッグシンボルが生成されていないのではないでしょうか。
また、ビルドコマンドに_-gsplit-dwarf
_を追加しようとしましたが、効果はありませんでした。
これが私の「hello world」バージョンのリンクコマンドです。
clang ++ main.o -L/usr/local/lib -g -o hello
実行可能ファイルとオブジェクトファイルに対してdwarfdump
( ここで読みます )を実行しました。デバッグシンボルareのように、訓練されていないように見えますが、実行可能ファイル自体にはありません(dwarfdump
がオブジェクトファイルでのみ機能する場合を除きます)。リンク段階が問題かもしれません。または、DWARFに問題がある可能性があります。
端末でビルドコマンドを1つずつ発行することで、「hello world」プログラムでこれを機能させることができました。したがって、これは私のビルドシステム( Tup )の問題である可能性があると思います。おそらく、異なる作業ディレクトリでコマンドを実行して、パスが壊れるなどの問題が発生する可能性があります。
-gコマンドラインオプションをclangに追加すると、DWARFデバッグ情報が_.o
_ファイルに書き込まれます。オブジェクトファイル(_.o
_、ranlibアーカイブ、または_.a
_ファイル)を実行可能ファイル/ dylib/framework/bundleにリンクすると、実行可能ファイルに「デバッグノート」が書き込まれ、(1)デバッグ情報を含む_.o
_などのファイルの場所、および(2)実行可能バイナリ内の関数/変数の最終アドレス。最適化フラグ(_-O0
_、_-O2
_など)は、デバッグ情報の生成に影響を与えません。ただし、最適化でコンパイルされたコードのデバッグは、_-O0
_でビルドされたコードのデバッグよりもはるかに困難です。
その実行可能バイナリでデバッガを実行すると、他の変更はありません。デバッガは、_.o
_ etcファイルからデバッグ情報を読み取ります実行可能ファイルをビルドしたときと同じファイルパスのファイルシステムにまだ残っています。これにより、反復的な開発が迅速になります。ツールは、(大きな)デバッグ情報を読み取り、更新、出力する必要はありません。 _nm -pa exename
_を実行してOSO
エントリを検索することにより、これらの「デバッグノート」を実行可能ファイルで確認できます。これらはstabs nlistエントリであり、実行可能ファイルでstrip(1)
を実行すると削除されます。
すべてのデバッグ情報(_.o
_ファイル内)をスタンドアロンバンドルに収集する場合は、実行可能ファイルに対してdsymutil
を実行します。これは、デバッグノート(仮定:(1)_.o
_ファイルがまだ元の場所にあり、(2)実行可能ファイルが削除されていない)を使用して、「dSYM
バンドル」を作成します。バイナリがexenameの場合、dSYMバンドルはexename.dSYMになります。デバッガーがexenameで実行されると、dSYMバンドルのそのバイナリーの隣を探します。そこに見つからない場合は、Spotlight検索を実行して、dSYMがコンピュータ上のSpotlightでインデックス付けされた場所にあるかどうかを確認します。
_.o
_ファイルまたはdSYMバンドルでdwarfdump
を実行できます。どちらにもデバッグ情報が含まれています。 dwarfdump
は、出力実行可能ファイルにデバッグ情報を見つけません。
したがって、通常のワークフロー:-gでコンパイルします。実行可能イメージをリンクします。反復的な開発の場合は、デバッガーを実行します。バイナリを配布/アーカイブする場合は、dSYMを作成し、実行可能ファイルを削除します。
(lldb) target symbols add a.out.dSYM
コマンドを使用して、a.out.dSYMディレクトリにあるデバッグシンボルへのパスを追加することで解決しました。