7

複数の共有ライブラリと実行可能ファイルをビルドするプロジェクトをビルドしています。これらのバイナリのビルドに使用されるすべてのソース ファイルは、単一の /src ディレクトリにあります。そのため、各バイナリのビルドにどのソース ファイルが使用されたかを特定することは明らかではありません (多対多の関係があります)。

私の目標は、バイナリごとに一連の C ファイルを解析し、それらから適切な関数のみが呼び出されるようにするスクリプトを作成することです。

1 つのオプションは、この情報を Makefile から抽出しようとすることです。ただし、これは生成されたファイルとヘッダーではうまく機能しません (インクルードに依存するため)。

単純にコール グラフを参照することもできますが、多くの関数が関数ポインターを使用して呼び出されるため、これは複雑になります。

他のアイデアはありますか?

4

5 に答える 5

10

最初にプロジェクトをデバッグ情報 (gcc -g) でコンパイルし、objdumpどのソース ファイルが含まれているかを取得するために使用できます。

objdump -W <some_compiled_binary>

Dwarf 形式には、探している情報が含まれている必要があります。

 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    < c>   DW_AT_producer    : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x28): test_3.c    
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x36): /home/auselen/trials    
    <19>   DW_AT_low_pc      : 0x82f0   
    <1d>   DW_AT_high_pc     : 0x8408   
    <21>   DW_AT_stmt_list   : 0x0  

この例では、test_3 からオブジェクト ファイルをコンパイルし、.../trials ディレクトリに配置しました。次に、もちろん、関連するソース ファイル名を収集するために、これに関するスクリプトを作成する必要があります。

于 2012-08-29T21:38:49.583 に答える
2

UNIXnmツールを使用できます。オブジェクトで定義されているすべてのシンボルが表示されます。したがって、次のことを行う必要があります。

  1. バイナリで実行nmし、未定義のシンボルをすべて取得します
  2. バイナリで実行lddして、すべての動的依存関係のリストを取得します(バイナリがリンクされている.soファイル)
  3. 手順2で見つかっnmた各ファイルで実行します。.so

これにより、バイナリが使用する動的シンボルの完全なリストが得られます。

例:

nm -C --dynamic /bin/ls
....skipping.....
00000000006186d0 A _edata
0000000000618c70 A _end
                 U _exit
0000000000410e34 T _fini
0000000000401d88 T _init
                 U _obstack_begin
                 U _obstack_newchunk
                 U _setjmp
                 U abort
                 U acl_extended_file
                 U bindtextdomain
                 U calloc
                 U clock_gettime
                 U closedir
                 U dcgettext
                 U dirfd

大文字の「U」が付いたこれらの記号はすべて、lsコマンドで使用されます。

于 2012-08-29T21:34:04.020 に答える
2

これがアイデアです。特定のビルドに基づいて改良する必要があります。ビルドを作成し、スクリプトを使用してログに記録します (例: script log.txt make clean all)。最後の (または最後の 1 つ) ステップは、オブジェクト ファイルのリンクです。(ヒント: を探してくださいcc -o <your_binary_name>)。その行は、ツリーに.o対応するファイルがあるはずのすべてのファイルをリンクする必要があります。次に、含まれているすべてのヘッダー ファイルについて、.cこれらのファイルを grepします。.c

ツリー内のファイルに重複した名前がある場合.cは、リンカー行のフル パスを確認するか、Makefile.

以下でマフムードが提案することもうまくいくはずです。シンボルを含むイメージがある場合strings <debug_image> | grep <full_path_of_src_directory>、C ファイルのリストが表示されます。

于 2012-08-29T21:22:02.203 に答える
2

最初に、コンパイルしたばかりのバイナリからデバッグ シンボルを分離する必要があります。その方法については、この質問を確認してください: ビルド ターゲットの外で gcc デバッグ シンボルを生成する方法は?

次に、このファイルを自分で解析してみることができます。Visual Studio でこれを行う方法は知っていますが、GCC を使用しているため、これ以上お手伝いすることはできません。

于 2012-08-29T21:23:22.207 に答える
1

C ソース ファイルを解析することが目的の場合は、GCC コンパイラをカスタマイズすることで実行できます。その目的でMELTを使用することもできます(MELT は GCC を拡張するための高レベルのドメイン固有言語です) - GCC 内で MELT でコード化された独自の分析パスを追加する - ただし、最初に GCC ミドルエンドの内部表現 (Gimple、Tree) について学ぶ必要があります。 、...)。

GCC のカスタマイズには数日かかります (主に GCC の内部は細部が非常に複雑であるため)。

MELTについてお気軽にご相談ください。

于 2012-08-30T08:22:44.943 に答える