Вопрос GDB с программой на C - PullRequest
2 голосов
/ 24 мая 2011

Здесь я рассматриваю простую программу, написанную на C, которая сохраняет указатель на строку с надписью «Hello, world! \ N»

Вот вывод моей GDB ... I 'Я в замешательстве из-за несоответствия GDB и что здесь находится:

$ gcc -g pointer.c
$ gdb -q ./a.out
Reading symbols for shared libraries .. done
(gdb) list
1   #include <stdio.h>
2   #include <string.h>
3   
4   int main() {
5     char str[20];
6     char *pointer;
7   
8     strcpy(str, "Hello, world!\n");
9     pointer = str;
10    printf("%s",pointer);
(gdb) 
11  }
(gdb) break 10
Breakpoint 1 at 0x100000ed1: file pointer.c, line 10.
(gdb) run
Starting program: /Users/___/a.out 
Reading symbols for shared libraries +. done

Breakpoint 1, main () at pointer.c:10
10    printf("%s",pointer);
(gdb) print pointer
$1 = 0x7fff5fbff950 "Hello, world!\n"
(gdb) print &pointer
$2 = (char **) 0x7fff5fbff948
(gdb) x/s 0x7fff5fbff950
0x7fff5fbff950:  "Hello, world!\n"
(gdb) x/16b 0x7fff5fbff950
0x7fff5fbff950:  "Hello, world!\n"
0x7fff5fbff95f:  ""
0x7fff5fbff960:  "x??_?"
0x7fff5fbff967:  ""
0x7fff5fbff968:  "՝?Y4?K\033???_?"
0x7fff5fbff977:  ""
0x7fff5fbff978:  "?\016"
0x7fff5fbff97b:  ""
0x7fff5fbff97c:  "\001"
0x7fff5fbff97e:  ""
0x7fff5fbff97f:  ""
0x7fff5fbff980:  ""
0x7fff5fbff981:  ""
0x7fff5fbff982:  ""
0x7fff5fbff983:  ""
0x7fff5fbff984:  ""
(gdb) x/x 0x7fff5fbff950
0x7fff5fbff950: 0x48
(gdb) x/x 0x7fff5fbff951
0x7fff5fbff951: 0x65
(gdb) x/s 0x7fff5fbff951
0x7fff5fbff951:  "ello, world!\n"
(gdb) print &pointer
$3 = (char **) 0x7fff5fbff948
(gdb) x/x 0x7fff5fbff948
0x7fff5fbff948: 0x00007fff5fbff950
(gdb) x/x 0x7fff5fbff949
0x7fff5fbff949: 0x4800007fff5fbff9
(gdb) x/2x 0x00007fff5fbff950
0x7fff5fbff950: 0x77202c6f6c6c6548  0x00000a21646c726f

Мои вопросы:

Сколько байтов информации хранится в одном из этих мест в памяти?Когда я нахожусь по адресу 0x7fff5fbff950, содержимое выглядит как 0x48 (ASCII 'H').Значит ли это, что для каждого адреса памяти хранится только один байт информации?ХОРОШО.Давайте предположим, что это так.Затем я запускаю ту же команду «x / x» по адресу, указанному print & pointer: 0x7fff5fbff948

Я получил значение 0x00007fff5fbff950, которое я распознаю (игнорируя ведущие нули) как начало «Hello, world»! \ n "строка в памяти.

Теперь, как 0x00007fff5fbff948 может содержать 0x00007fff5fbff950 и при этом иметь только один байт памяти?Итак, я смотрю на 0x00007fff5fbff949 ... и теперь это снова говорит мне, что мы смотрим только на байт каждый раз, так как мы потеряли конечный 0x50 (я знаю little-endian, так что, возможно, я формулирую это смущающе).

Теперь я действительно злюсь ... Я пытаюсь сделать x / 2x 0x7fff5fbff948, и на меня нападают два гигантских шестнадцатеричных числа ...

Таким образом, данные в памяти хранятся байт за раз,и как-то х / х иногда дает мне один байт на память, а иногда дает мне полный адрес?Как я могу контролировать то, что будет выводить отладчик?х / х следует проверить содержимое этого адреса и вывести в шестнадцатеричном виде.Я могу использовать x / b для одного байта, x / 2b для 2 байтов ... но x / 2x означает что?

Извините за поток вопросов о сознании ... надеюсь, кто-то может помочь мне разобраться с этим.

1 Ответ

2 голосов
/ 24 мая 2011

Память имеет адрес адресуемый байт , означающий, что каждый байт имеет отдельный адрес.Затем вы можете интерпретировать , например, пару байтов как 16-разрядное целое число, четыре байта как 32-разрядное целое число и т. Д. Этот спецификатор формата позволяет вам делать это - печатать содержимое памяти в соответствии с вашей интерпретациейэтогоТаким образом, x/2x 0x7fff5fbff948 напечатает два целых числа размером в слово (здесь 64-разрядные), сначала по адресу 0x7fff5fbff948, а затем по адресу 0x7fff5fbff950.

...