2012-02-02 10 views
5

タイトルにあるように、Cのプログラムでスタックの内容を表示したいと思います。ここでスタックの内容をCプログラムで印刷するにはどうしたらいいですか?

は私が撮った手順は次のとおりです。

  • 私は私のアドレスを返すために私EBPレジスタと関数のアドレスを返すために機能を含め、簡単な組立(helper.s)ファイルを作りましたESP

    .globl get_esp 
    
    get_esp: 
        movl %esp, %eax 
        ret 
    # get_ebp is defined similarly, and included in the .globl section 
    
  • を登録し、私は私のCプログラム(FPCがintであるfpC = get_esp();
  • I(成功し、私は思う)、印刷からget_esp()get_ebp()関数と呼ば私のespとebpレジスタのアドレスを編集しました。(fprintf (stderr, "%x", fcP);
  • 私のespレジスタの内容を印刷しようとしましたが失敗しました。 (他の方法の中でもfprintf (sderr, "%d", *fcP);fprintf (sderr, "%x", *((int *)fcP));を試しました)。この行が処理されると、私のプログラムは実行時にセグメンテーション違反に遭遇します。

私は間違っていますか?

EDIT:これは、スタックポインターを取得するためにこれらのアセンブリ関数を呼び出すことによって実行する必要があります。 EDIT2:これは宿題です。

+0

あなたはそれが失敗したと言いますとどういう意味ですか?あなたはどのようなアウトプットを得ましたか、何を期待しましたか? –

+0

ポインタを出力するには、printf( "%p"、(void *)(p)) 'を使用する必要があります。 "%espの内容"はポインタです。 –

+0

@CarlNorum:いいえ、 'printf'の使用はC標準によって単に義務付けられています。 –

答えて

5

GNUシステムを利用している場合は、バックトレースを処理するためにCライブラリにGNUの拡張機能を使用することができます。hereを参照してください。

#include <execinfo.h> 

int main(void) 
{ 
    //call-a-lot-of-functions 
} 

void someReallyDeepFunction(void) 
{ 
    int count; 
    void *stack[50]; // can hold 50, adjust appropriately 
    char **symbols; 

    count = backtrace(stack, 50); 
    symbols = backtrace_symbols(stack, count); 

    for (int i = 0; i < count; i++) 
     puts(symbols[i]); 

    free(symbols); 
} 
+0

これはうまくいくように見えますが、アセンブリ機能(割り当てごとの要件)を使用してこれを実装する必要があります。私はそれを私の問題で最初に指定すべきでした。 – Nate

+0

宿題を宿題としてマークすることが重要です。 – dreamlax

+0

申し訳ありません。元の投稿を編集しました。 – Nate

4

get_esp戻りespそれは関数内であるように。呼び出し操作がespのため、これは呼び出し元関数のespと同じではありません。

この機能をインラインアセンブリで置き換えることをお勧めします。この方法でespは読んだときに変更されません。

また、sderrに印刷しても役に立ちません。私の経験から、stderrがはるかに優れています。

関連する問題