問題タブ [dwarf]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C 関数ポインタの関数名を取得する方法
次の問題があります: backtrace(3) 関数を使用して C でバックトレースを取得すると、関数の名前が返されたシンボルは、dwarf ライブラリと dladdr(3) で簡単に判別できます。
問題は、単純な関数ポインターがある場合 (たとえば&functionを渡すことによって)、dladdr + dwarf 関数が役に立たないことです。ポインターが backtrace(3) によって返されるものとは異なるようです (backtrace はこれらの関数ポインターをスタックから直接取得するため、おかしなことではありません)。
私の質問は、これらの名前も解決する方法があるかどうかです。また、2つのポインターの違いを正確に知りたいです。
ありがとう!
アップデート:
ポインター間の違いは非常に重要です:
バックトレースで得られるものは: 0x8048ca4
ダイレクト ポインター バージョン: 0x3ba838
2番目のものにはオフセットが必要なようです。
stack-unwinding - dwarf2でスタックの巻き戻し中にスタックポインタの値を取得する
DWARF2 デバッグ形式では、.debug_frame セクションにある CFI (Call Frame Information) の助けを借りて、スタックの巻き戻しがサポートされます。これはまさに、すべてのレジスタが前のフレームで値を取得するためのルールを保持するテーブルです。ただし、これらのルールはすべて、レジスタがスタック上のある場所に保存されるという事実に依存しています。これは、フレーム ポインターがない場合に前のフレーム レジスターでスタック ポインターの値を取得する場合には当てはまりません。このような場合、スタック ポインタはスタックに保存されず、その値をインクリメントおよびデクリメントするだけで管理される場合があります。ただし、dwarf2 (または一般的には dwarf 形式) では、レジスタ値が現在の値を超える式であることを示す方法はありません。したがって、私の質問は、dwarf2 デバッグ形式でスタックの巻き戻し中にスタック ポインターの値を取得する方法です (フレーム ポインターがない場合)。
-BV
debugging - dwarf2でのスタックの巻き戻し
dwarf2でスタックを巻き戻すことで、いくつかの非常に基本的なABI(アプリケーションバイナリインターフェイス)シナリオで引数の信頼性の高い回復がどのように保証されるかを理解していません。ABIについて考えてみましょう。これは、最初の3つの引数がレジスターにあり、スタックにある必要があることを示しています。私が理解しているように、dwarf2スタックの巻き戻しメカニズムにより、CFIテーブルが適切に満たされている場合、現在のフレームの呼び出しポイントでレジスタの値を取得できます。ただし、これでは、呼び出し元のプロローグに移動して、引数レジスタの内容を知ることはできません。したがって、同じフレーム内の異なるポイントでもレジスタの値を見つける方法があったはずです(.debug_frameセクションでエンコードされたテーブルは、前のフレームの場所のみを示しています)。
私の理解に何か問題がありますか?このような場合、dwarf2デバッグ形式に基づくデバッガーはどのように機能しますか?引数がスタックで渡されるアーキテクチャの場合、プログラム内のすべてのポイント(任意のフレーム)で値を回復するための問題はありません。
debugging - DWARF情報を使用してメモリアドレスを行番号にマップします
メモリを介してプログラムの実行を追跡するアプリケーションがあります。を使用readelf --debug-dump=decodedline
してメモリアドレス/行番号情報を取得しようとしましたが、表示されるメモリアドレスは、そのダンプによって指定されたものと頻繁に一致しません。各アドレスをDWARFデータに表示される「最新の」アドレスと一致させるために何かを書きました。これはいくつかのことをクリーンアップしたように見えましたが、それがこのデータを解釈する「公式」の方法かどうかはわかりません。
誰かがDWARFを使用してプログラムアドレスを行番号にマップする正確なプロセスを説明できますか?
gdb - プログラム全体のライブラリのデバッグシンボルから行番号が欠落していますが、それ自体ではありません
gdbを使用してlibtoolでビルドされたパッケージのテストプログラムをデバッグしようとすると、奇妙な問題が発生します。実行libtool --mode=execute gdb .libs/libfoo.so
して関数のソースをリストするように依頼するとlist Bar::Baz
、期待どおりにソースコードが取得されます。を実行するlibtool --mode=execute gdb binary
と、侵入しBar::Baz()
てスタックトレースでその引数を確認できますが、次のようにソースファイルまたは行番号を取得できません。
同様にlist Bar::Baz
、実行可能ファイルをデバッグしようとすると、次のようになります。
バイナリがとリンクされていることを確認し、-g
その機能を一覧表示できるmain
ので、デバッグ情報の一部が存在することがわかります。
と言うとinfo sources
、ライブラリが構築されているファイルの完全なリストと、正しい絶対パスが表示されます。と言うとinfo shared
、オブジェクトファイルへの正しいパスがリストさYes
れ、Syms
列にが表示されます。
何がうまくいかない可能性があり、それを修正する方法についてのさらなるアイデアはありますか?
編集1:誤っobjdump -g
て、問題のあるライブラリを実行し、次の出力を取得しました。
objdump -h
(私が実行しようとしたもの)にはたくさんの.debug_*
セクションがリストされているので、これは驚くべきことです。objdump
マニュアルreadelf -w
も同様に示唆しており、それは膨大な情報の山を印刷しているようです。ただし、実際に何が提供されるかを確認する必要があります。
編集2:それで、readelf -w
いくつかの悟りを生み出しました。何らかの理由で、共有オブジェクトファイルには、リンクされているオブジェクトの大部分 からのデバッグ情報が含まれていないようです。Makefilesに基づいて、オブジェクトを共有ライブラリに実際に収集するコマンドが渡されず、情報が適切に伝播されない可能性があります。面白いことに、これは(現在のx86に対して)x86_64の同じコンパイラバージョンを含む、他のすべての構成で機能します(完全なデバッグ情報があります)。-g
編集3:実際には、LDFLAGSに-gが追加された変更されたMakefileを使用して完全に再構築されましたが、違いはありませんでした。今、私は元気で本当に困惑しています。
ios - リリース ビルド用の dSYM ファイル
.dSYM
リソースには DWARF 情報以外の情報が含まれていますか? アプリのリリース ビルドを作成しました。これを実行dwarfdump
すると、実行可能ファイルに DWARF 情報がない (「空」である) と表示されますが、これは私が期待することです。しかし、それを実行dsymutil
すると、空でないシンボル ファイルが作成されます。これらはバイナリ ファイルなので、何が入っているかわかりません。誰でもこれについて教えてもらえますか?これらのファイルのビューアはありますか?
c++ - clang による C++ の表現
C++ (C ではない) ソース情報を表現するために clang が使用するクラスを知りたい
DWARF( http://en.wikipedia.org/wiki/DWARF )で役立つ内部表現が必要です。たとえば、タイプの関連情報は、このタイプのバイト単位のサイズ、バイトアライメントこのタイプなど
LLVM + Clang をダウンロードしました。http://clang.llvm.org/docs/InternalsManual.htmlを見ましたが、答えが見つからなかったので、誰かが私に何かを見逃して、このデータの検索を開始する必要があるクラスを教えてもらえますか?
compiler-construction - ELF エンディアン データ形式の変更
ビッグ エンディアンとリトル エンディアンの ELF/DWARF ファイルの両方で動作するようにソフトウェアを編集しようとしています。そのためには、同じデータの Little ELF ファイルと Big ELF ファイルの両方を用意することをお勧めします。コンパイラで単純なプログラムを使用して ELF オブジェクト ファイルを作成していますが、オブジェクト ファイルは常に、使用しているチップのアーキテクチャのエンディアンでフォーマットされています。1 つのチップで 1 つのプログラムの両方のエンディアンを取得する方法はありますか?
ありがとう。
c++ - LLVMの例外。くつろぐ方法
現在、CreateEntryBlockAllocaを使用してブロックスコープの先頭に変数を挿入しています。
ここで、非PODタイプのAllocasを追加したいと思います(終了時にデストラクタ/クリーンアップ関数が必要になる場合があります)。ただし、通常のDWARF例外がスローされたときにデストラクタ呼び出しを呼び出す方法が明確でないため、exitスコープブロックの最後にデストラクタ呼び出しを追加するだけでは不十分です(この引数の目的で、例外がPODタイプのみをスローするC++関数を呼び出すCallポイントからスローされるため、私の場合、無知は至福であり、理解が深まらない限り、固有のllvm例外を避けたいと思います)。
Allocaレジスタを使用してスタックにオフセットを持つテーブルを作成し、例外ハンドラ(スタックの最下部、JIT関数の呼び出しポイント)にテーブル上のそれらのオフセットをウォークオーバーさせることができるのではないかと考えていました。デストラクタを適切に呼び出します。
私が知らないのは、CreateAllocaで作成されたAllocaされたレジスタのオフセットをクエリする方法です。どうすればそれを確実に行うことができますか?
また、これを達成するためのより良い方法があると思われる場合は、llvmのパスについて教えてください
- テクニカルコメント:JITコードはboost :: context内で呼び出され、try catch内でのみJITコードを呼び出し、catchに対しては何も実行せず、コンテキストを終了してメインの実行スタックに戻ります。メインの実行スタックでアンワインドを処理する場合、呼び出す関数(たとえば、スタック変数のクリーンアップ)は、終了したJITコンテキストから同じスタックの内容を上書きしないため、破損することはありません。私が十分に理にかなっていることを願っています
assembly - GAS: .cfi_def_cfa_offset の説明
GCC で生成されたアセンブリの .cfi_def_cfa_offset ディレクティブで使用される値について説明が必要です。.cfi ディレクティブが呼び出しフレームとスタックの巻き戻しに関与していることは漠然と知っていますが、たとえば、次の C プログラムをコンパイルする際に、GCC が出力するアセンブリで値 16 と 8 が使用されている理由について、より詳細な説明が必要です。私の64ビットUbuntuマシンで。
C プログラム:
次のように、ソース ファイル test.c で GCC を呼び出しましたgcc -S -O3 test.c
。-O3 によって非標準の最適化が可能になることはわかっていますが、簡潔にするために、生成されるアセンブリのサイズを制限したかったのです。
生成されたアセンブリ:
生成されたアセンブリで .cfi_def_cfa_offset ディレクティブに値 16 と 8 が使用されるのはなぜですか? また、ローカル関数の開始ラベルと関数終了ラベルに 22 という数字が使用されているのはなぜですか?