10

編集(更新された質問)

私は簡単なCプログラムを持っています:

   // it is not important to know what the code does you may skip the code 

main.c

#include <bsp.h>

unsigned int   AppCtr;
unsigned char  AppFlag;
int SOME_LARGE_VARIABLE;

static  void  AppTest (void);

void  main (void)
{
    AppCtr  = 0;
    AppFlag = 0;        
    AppTest();
}

static void Foo(void){
    SOME_LARGE_VARIABLE=15; 
}


static  void  AppTest (void)
{
    unsigned int  i;
    i = 0;
    while (i < 200000) {
        i++;
    }

    BSP_Test();      
    SOME_LARGE_VARIABLE=3;    
    Foo();
}

bsp.c

extern int SOME_LARGE_VARIABLE;
extern unsigned char  AppFlag;

unsigned int long My_GREAT_COUNTER;

void  BSP_Test (void) {
  SOME_LARGE_VARIABLE = 5;
  My_GREAT_COUNTER = 4;
}

(プログラムは何も役に立ちません...私の目標は、変数名を宣言されている場所とメモリアドレスを抽出することです

プログラムをコンパイルすると、a.outデバッグ情報を含むelfファイルであるファイルが取得されます。

会社の誰かが5年前に.netで、このすべての情報をa.outファイルから取得するプログラムを作成しました。これはコードが返すものです:

   //  Name          Display Name                    Type      Size     Address

ここに画像の説明を入力してください

この小さなプログラムでは、それはうまく機能し、他の大規模なプロジェクトでも機能します。

そのコードは2000行の長さで、いくつかのバグがあり、.NETバージョン4をサポートしていません。そのため、私はそれを再作成しようとしています。


ですから、私の質問は、この問題を解決するためにどのようなアプローチを取るべきかわからないという意味で迷子になっています。これらは私が検討してきたオプションです:

  1. 最初の画像で示したプログラムのバグのあるコードを整理し、その情報を取得するために、プログラムが何を実行し、a.outファイルをどのように解析するかを確認してください。完全に理解したら、バージョン3および4をサポートしない理由を理解してください。

  2. 私は正規表現を作成しても大丈夫なので、次のようにしてa.outファイルでパターンを探してみてください。ここに画像の説明を入力してください これまでのところ、ファイルが1つしかないパターン(main.c)を見つけることができました。ただし、ファイルが複数ある場合は、さらに複雑になります。まだ試していません。多分それはそれほど複雑ではなく、パターンを見つけることが可能になるでしょう。

  3. Cygwinをインストールして、、、などのWindowsでLinuxコマンドを使用できるようにobjdumpnmますelfreadreadelf -w a.out必要な情報が得られるなど、これらのコマンドを使用するときは、コマンドを十分に試していません。私がこのアプローチにそれほど多くの時間を費やしていない理由にはいくつかの短所があります:

    • 短所:Windowsにcygwinをインストールするのに時間がかかります。このアプリケーションをお客様に提供する場合、お客様にインストールする必要はありません。たぶん、全部をインストールすることなく、コマンドobjdumpとelfreadをインストールする方法があるでしょう。

    • 長所:使用する適切なコマンドが見つかった場合、車輪の再発明を行わず、時間を節約できます。多分それは次のようなコマンドの結果を解析することの問題ですobjdump -w a.out


ここで解析するためにa.outファイルをダウンロードする場合は、です。


概要

.outファイルでグローバル変数を取得できるようになります。各変数のタイプ(int、char、..)、変数のメモリアドレス、および変数が宣言されているファイル(main.cまたはsomeOtherFile.c)についても知りたいと思います。cygwinを使用する必要がない場合は、展開がより簡単になりますので、よろしくお願いします。この質問は多くのことを求めているので、私はそれをもっと分割しようとしました:

おそらく他の質問を削除する必要があります。冗長でごめんなさい。

4

1 に答える 1

14

これが私がすることです。なぜ車輪の再発明を!

  1. ここからWindowsで必要になるLinuxコマンドをダウンロードします。

    binディレクトリには次のものがあります。readelf.exe

    Cygwinやプログラムは必要ないので、デプロイは簡単です。

  2. そのファイルをcmdで実行したら、次のようにします。

    // cd "path where readelf.exe is"
    readelf.exe -s a.out
    

    そしてこれが出てくるリストです: ここに画像の説明を入力してください

    したがって、見てみると、サイズが0より大きいOBJECT型のすべての変数を取得することに関心があります。

  3. 変数を取得したら、readelf.exe -w a.outコマンドを使用してツリーを確認できます。次のようになりここに画像の説明を入力してくださいます。手順2で見つけた変数の1つ(SOME_GREAT_COUNTER)を探し始めましょう。上部で変数の場所がわかっていることに注意してください。宣言されているときに、宣言された行やメモリアドレスなどの詳細情報を取得しました

  4. 私たちがしなければならない最後のことは、型を取得することです。見てみると、タイプは=<0x522>であることがわかります。つまり、その時間に関する詳細情報を取得するには、ツリーの522に移動する必要があります。その部分に行くと、これが得られます。ここに画像の説明を入力してくださいツリーを見ると、SOME_LARGE_VARIABLEの型がunsignedlongであることがわかります。

于 2012-06-15T19:01:23.597 に答える