2012-08-29 10 views
6

私は、複数の共有ライブラリと実行可能ファイルをビルドするプロジェクトを構築しています。これらのバイナリのビルドに使用されるすべてのソースファイルは、単一の/ srcディレクトリにあります。だから、どのバイナリをビルドするためにどのソースファイルが使われたのかは分かりません(多対多の関係があります)。バイナリを構築するために使用された* .cと* .hファイルを見つける方法?

私の目標は、各バイナリのCファイルのセットを解析し、正しい関数だけが呼び出されるようにするスクリプトを作成することです。

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

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

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

+1

ちょっと好奇心から:これはなぜあなたが試していますか? – stefan

+0

ディストリビューションパッケージのメカニズムは、すべての依存関係を知っています... –

+0

"適切な機能と呼ばれる"という意味の正確な定義はありますか?それは明らかではなく、単純ではありません。 –

答えて

6

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

objdump -W <some_compiled_binary> 

ドワーフフォーマットには、探している情報が含まれている必要があります。

<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からオブジェクトファイルをコンパイルしましたが、このファイルは.../trialディレクトリにあります。もちろん、関連するソースファイル名を収集するために、このスクリプトを書く必要があります。

2

ここでは、特定のビルドに基づいて詳細を絞り込む必要があります。ビルドを行い、スクリプトを使用してログに記録します(たとえば、script log.txt make clean all)。最後の(または最後の)ステップは、オブジェクトファイルのリンクでなければなりません。 (ヒント:cc -o <your_binary_name>を探してください)。その行は、対応する.cファイルをツリー内のすべての.oファイルにリンクする必要があります。その後、インクルードされたすべてのヘッダーファイルについて、それらのファイルに.cをgrepします。

ツリー内の.cファイルに重複する名前がある場合は、リンカー行のフルパスを調べるか、Makefileから作業する必要があります。

Mahmoodが以下に示唆するものはあまりにもうまくいくはずです。シンボルを持つ画像がある場合は、strings <debug_image> | grep <full_path_of_src_directory>はCファイルのリストを提供するはずです。

+0

あまりにも良いアイデアです。しかし、私はGCCのMakefilesに精通していませんが、私はVSで行います.VSは、リンク先のライブラリファイルを簡単に一覧表示するための詳細を示していません。 –

2

まず、コンパイルしたばかりのバイナリからデバッグシンボルを分離する必要があります。これを行う方法についてこの質問を確認してください。 How to generate gcc debug symbol outside the build target?

次に、このファイルを自分で解析することができます。私はVisual Studioのためにそうする方法を知っていますが、GCCを使用しているので、私はあなたをさらに助けることができません。

+0

これもうまくいくはずです! – jman

1

unix nmツールを使用できます。オブジェクトに定義されているすべてのシンボルを表示します。

  • (.soのバイナリがにリンクされているファイル)そのすべての動的依存関係のリストをつかむためにあなたのバイナリ上のすべての未定義のシンボル
  • 実行lddをバイナリに

    1. 実行nmをしてつかむ:だからあなたがする必要があります各.soファイルにnmを実行するには、あなたのバイナリを使用ダイナミックシンボルの完全なリストを提供します

    ステップ2で見つけyouf。

    例:

    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コマンドで使用されています。

  • 1

    あなたの目標がCソースファイルを分析することであれば、GCCコンパイラをカスタマイズすることでそれを行うことができます。その目的のためにMELTを使用することができます(MELTはGCCを拡張するための高水準のドメイン固有の言語です)。 - GCC内部のMELTでコード化された独自の解析パスを追加していますが、GCC中間の内部表現(Gimple、Tree 、...)。

    GCCのカスタマイズには数日間の作業が必要です(主に、GCCの内部構造は非常に複雑です)。

    MELTについてもっとお気軽にお問い合わせください。

    関連する問題