2016-09-13 9 views
1

私のバイナリを実行しているときに、GDBが配列をダンプしないことがわかりました。なぜこれが実行可能ファイルのいくつかでのみ起こるのか分かりません。なぜGDBが配列を出力していないのですか?

宣言は非常に単純です:

tbl_account_t  accounts[MAX_ACCOUNTS]; 

私はアレイ(ただの配列)を印刷するとき、私はこれを取得:変数の型を確認

(gdb) print accounts 
$16 = 0x618d20 <accounts> 

は、すべてがOKです:

(gdb) ptype accounts 
type = struct tbl_account { 
    unsigned short email_len; 
    unsigned short password_len; 
    char auto_log_in; 
    char reserved_char[3]; 
    int reserved_int; 
    char email[64]; 
    char password[25]; 
} [] 
(gdb) 

私はデータを持っています:

(gdb) print accounts[1] 
$18 = {email_len = 16, password_len = 3, auto_log_in = 0 '\000', reserved_char = "\000\000", reserved_int = 0, email = "[email protected]", '\000' <repeats 47 times>, 
    password = "123", '\000' <repeats 21 times>} 
(gdb) 

"print accounts"コマンドを使用して、の内容を他の実行可能ファイルと同様にダンプすることを期待していました。なぜこれが起こるのですか?

答えて

1

私は完全な答えはありませんが、あなたのコードをもっと分かち合うと分かります。 gdbはあなたの配列の長さを知らないようです。

は、このプログラム今

struct tbl_account { 
    unsigned short email_len; 
    unsigned short password_len; 
    char auto_log_in; 
    char reserved_char[3]; 
    int reserved_int; 
    char email[64]; 
    char password[25]; 
}; 


int main(int argc, char* agv[]) 
{ 

tbl_account table[10]; 
tbl_account* table_ptr = table; 
return 0; 
} 

GDBセッションポインタのp型が '*' で示される方法

(gdb) b main 
Breakpoint 1 at 0x4006e5: file junk.cpp, line 22. 
(gdb) r 
Starting program: /tmp/a.out 

Breakpoint 1, main (argc=1, agv=0x7fffffffdfe8) at junk.cpp:22 
22 tbl_account* table_ptr = table; 
(gdb) n 
23 return 0; 
(gdb) ptype table_ptr 
type = struct tbl_account { 
    unsigned short email_len; 
    unsigned short password_len; 
    char auto_log_in; 
    char reserved_char[3]; 
    int reserved_int; 
    char email[64]; 
    char password[25]; 
} * 
(gdb) ptype table 
type = struct tbl_account { 
    unsigned short email_len; 
    unsigned short password_len; 
    char auto_log_in; 
    char reserved_char[3]; 
    int reserved_int; 
    char email[64]; 
    char password[25]; 
} [10] 

注考えてみましょう。配列の型は[10]で示されていることもわかります。私の例では、配列のサイズが含まれており、gdbは各要素を出力します。何らかの理由で、あなたの例では、配列のサイズは含まれていません。おそらくそれはexternの変数ですか?

gdbは配列のサイズを特定していないので、単にポインタ値として出力します。回避

(gdb) p (tbl_account[10])accounts

+0

感謝問題が何であるかを知るために私を助けました。 main.cにヘッダ "constants.h"が含まれていなかったので、これは私のソースコードでMAX_ACCOUNTSが宣言されている場所です。 GCCではこれは問題ではないので、コンパイルエラーはありません。しかし明らかにGDBはインクルードの下位階層でシンボル定義を検索しません。 #include "constants.h"をmain.c自身に追加することで、GDBはaccounts []配列のサイズを知ることができました。 – Nulik

+0

私はこれの本当の原因を発見しました。インクルード "constants.h"ではありませんでした。私はライブラリ関数内のコードをトレースしていましたが(私自身のライブラリですが、全く別の共有オブジェクトです)、ライブラリはこの宣言を使用しています: "extern tbl_account_t accounts []"、これがポインタだけが印刷された理由です。 – Nulik

+0

ハ!外部の推測でそれを命じた –

0

をキャストしようとしたよう手動でも「@」を使用して印刷する方法を多くのエントリGDBを伝えることができます。 これは、配列が静的に割り当てられていない場合や、配列内の特定のエントリを調べたい場合に効果的です。その後、

struct tbl_account { 
    int id; 
    char email[64]; 
    char password[25]; 
}; 

int main(void) 
{ 
    struct tbl_account table[] = { 
      {1, "abc", "1234"}, 
      {2, "def", "5678"}, 
      {3, "ghi", "1011"}, 
      {4, "jkl", "1213"}}; 

    return 0; 
} 

そして、あなたは例えばのための唯一の指標2-3に興味があるなら、あなたが行うことができ

(gdb) p table[0]@3 
$3 = {{ 
    id = 1, 
    email = "abc", '\000' <repeats 60 times>, 
    password = "1234", '\000' <repeats 20 times> 
    }, { 
    id = 2, 
    email = "def", '\000' <repeats 60 times>, 
    password = "5678", '\000' <repeats 20 times> 
    }, { 
    id = 3, 
    email = "ghi", '\000' <repeats 60 times>, 
    password = "1011", '\000' <repeats 20 times> 
    }} 

配列の最初の3つの項目を印刷するにはGDBを伝える -

(gdb) p table[2]@2 
$5 = {{ 
    id = 3, 
    email = "ghi", '\000' <repeats 60 times>, 
    password = "1011", '\000' <repeats 20 times> 
    }, { 
    id = 4, 
    email = "jkl", '\000' <repeats 60 times>, 
    password = "1213", '\000' <repeats 20 times> 
    }} 
関連する問題