2016-09-13 2 views
1

내 바이너리를 돌릴 때 GDB가 배열을 덤프하지 않는다는 것이 이상하게 느껴졌는데 왜 이것이 실행 파일의 일부에서만 발생하는지 알지 못합니다.GDB가 배열을 인쇄하지 않는 이유는 무엇입니까?

선언은 매우 간단합니다 :

tbl_account_t  accounts[MAX_ACCOUNTS]; 

내가 배열 (다만 어떤 배열)을 인쇄 할 때,이 얻을 : 변수 유형을 확인

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

이 모든 것이 괜찮 :

(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; 
} 

포인터의 p- 형이 '*'로 표시되는 방법을 GDB 세션

(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는 배열의 크기가 확실하지 않으므로 포인터 값으로 인쇄합니다. A가 해결할로

(gdb) p (tbl_account[10])accounts

+0

감사합니다 많은 문제가 무엇인지 알아 내도록 도왔습니다. main.c에 "constants.h"라는 헤더가 없으므로 MAX_ACCOUNTS가 내 소스 코드에서 선언되었습니다. GCC의 경우 이것은 문제가 아니므로 컴파일 오류가 없습니다. 그러나 분명히 GDB는 include의 하위 계층 구조에서 심볼 정의를 찾지 않습니다. #include "constants.h"를 main.c 자체에 추가함으로써 GDB는 accounts [] 배열의 크기를 알 수 있었고 지금은 괜찮습니다. – Nulik

+0

나는 이것의 진정한 원인을 발견했다. 그것은 "constants.h"를 포함하지 않았습니다.라이브러리 함수 (내 자신의 라이브러리이지만 완전히 다른 공유 객체) 내에서 코드를 추적하고 라이브러리에서 다음 선언을 사용하는 경우가 발생합니다. "extern tbl_account_t accounts []"이것은 포인터 만 인쇄 된 이유입니다. – Nulik

+0

하! extern guess와 함께 찍은 –

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> 
    }} 
관련 문제