2010-11-25 17 views
3

私はLinux上でgdbバージョン6.8-debianを使用しています。私はcプログラムの主な機能がどのように実行されて遊んでいて、別の場所を見ているのか不思議に思っていましたが、__libc_start_main関数がこれに応答していることがわかりました。 __libc_start_mainへの引数は次のとおりです。mainのアドレス(cからわかるように、パスは常にargv [0]として与えられます)、次にargsはレジスタESIになければなりません。argvの次のアドレスECXで。gdbでコマンドライン引数にアクセス

#include <stdio.h> 
#include <stdlib.h> 

int main (int argc, char *argv[]) 
{ 
    printf("%s: %s\n", "argv[1]", *++argv); 
    return EXIT_SUCCESS; 
} 

は、今私はデバッグCMDARGSに起動し、メインにブレークポイントを設定します。

周りに再生するには、私は単に開始時に与えられた最初のコマンドライン引数を出力し、次の簡単なプログラム、cmdargs.cを作っそして__libc_start_main(削除GDBを開始してからの情報):

のgdb CMDARGS

(gdb) b main 
Breakpoint 1 at 0x80483d2 
(gdb) b __libc_start_main 
Breakpoint 2 at 0xb7f3f5a8 
(gdb) r qwerty 

ここで私は[0]

(gdb) p $esi 

(gdb) x/s *($ecx) 

で期待通りにこれは動作しますが、どのように私は最初の非暗黙的にアクセスします__libc_start_mainにブレークポイント2を押すと、argcとargvのを見ることができますコマンドライン引数 "qwerty"?私はメインとブレークポイントでブレークポイントを継続しようとしましたが、argcとargvは認識されません(なぜ?)。誰かが何が起こっているか教えてもらえますか?

Breakpoint 1, 0x080483d2 in main() 
(gdb) stepi 
0x080483d5 in main() 
(gdb) p argc 
No symbol "argc" in current context. 
(gdb) p argv 
No symbol "argv" in current context. 
(gdb) 

答えて

1

出力は、デバッグ情報が不足しているように見えます。 GDBは住所だけでなく行番号も印刷するべきです。

(gdb) b main 
Breakpoint 1 at 0x400543: file test.c, line 3. 
(gdb) r test1 test2 
Starting program: /home/simon/a.out test1 test2 

Breakpoint 1, main (argc=3, argv=0x7fffffffdca8) at test.c:3 
3    puts("blabla"); 
(gdb) print argc 
$1 = 3 
(gdb) print argv 
$2 = (char **) 0x7fffffffdca8 
(gdb) print argv[0] 
$3 = 0x7fffffffe120 "/home/simon/a.out" 
(gdb) print argv[1] 
$4 = 0x7fffffffe132 "test1" 
(gdb) print argv[2] 
$5 = 0x7fffffffe138 "test2" 
(gdb) 
1

うん、あなたの問題は、シンボルの欠如、コンパイル時に含まれておりませんが..ですそれはあまりにもデバッグ情報を構築するように指示はgccに-gオプションを追加する必要があります。デバッグ情報を使ってコンパイルすること

その後
$ gcc -g3 cmdargs.c -o cmdargs 

$ gdb ./cmdargs 
... 
Reading symbols from ./cmdargs...done. 
(gdb) b main 
Breakpoint 1 at 0x400545: file cmdargs.c, line 6. 
(gdb) r 
Starting program: cmdargs 

Breakpoint 1, main (argc=1, argv=0x7fffffffdc28) at cmdargs.c:6 
6  printf("%s: %s\n", "argv[1]", *++argv); 
(gdb) p argc 
$1 = 1 
(gdb) p argv 
$2 = (char **) 0x7fffffffdc28 
(gdb) p *argv 
$3 = 0x7fffffffe00c "/home/jcgonzalez/cmdargs" 

を参照してください、今は(それらが認識されている)シンボルに、だけでなく、行番号へのアクセスを取得します。 Let_Me_Beに示すように、array [n]表記で単一配列要素にアクセスできますが、* array @ times表記ですべてのコマンドライン引数を([0] -edを含む)一度に表示することもできます。次の例の最初の引数は、引用符付きの文字列です。

(gdb) set args "this is an argument" these are four more 
(gdb) r 
Starting program: cmdargs "this is an argument" these are four more 

Breakpoint 1, main (argc=6, argv=0x7fffffffdbd8) at cmdargs.c:6 
6  printf("%s: %s\n", "argv[1]", *++argv); 
(gdb) p argc 
$4 = 6 
(gdb) p *[email protected]          
$5 = {0x7fffffffdfe6 "/home/jcgonzalez/cmdargs", 0x7fffffffdfff "this is an argument", 0x7fffffffe012 "these", 0x7fffffffe017 "are", 0x7fffffffe01b "four", 
    0x7fffffffe020 "more"} 
(gdb) p argv[1] 
$6 = 0x7fffffffdfff "this is an argument" 
(gdb) p argv[2] 
$7 = 0x7fffffffe012 "these" 
関連する問題