GDB Как вывести данные из структуры? - PullRequest
0 голосов
/ 15 октября 2018

Использование очень простого примера, который использует указатель int для указания на структуру с длинными значениями.Конечно, это не самый предпочтительный метод, но он делается для имитации другого кода.Цель состоит в том, чтобы просмотреть данные в реестре до бесплатного звонка.

Это код.

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

typedef struct
        {
        unsigned long   x;
        unsigned long   y;
        unsigned long   z;
        }
        myStruct;

int main () {
   int  *p_Struct = (int *)0;

   int size = sizeof (myStruct);

   printf("Size of (bytes)...\n");
   printf("     myStruct : %d\n", sizeof (myStruct));

   p_Struct = ( int*) malloc(size);
   memset((int *)p_Struct, 0, size);

   ((myStruct *)p_Struct)->x = 111;
   ((myStruct *)p_Struct)->y = 222;
   ((myStruct *)p_Struct)->z = 333;

   free(p_Struct);
   return(0);
 }

Использование следующей версии GDB для пошагового выполнения кода.

Использование> gdb GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7

Gdb используется для запуска приложения, затем разбирается для получения строки кода для свободной команды,

(gdb) disassemble main
Dump of assembler code for function main:
   0x000000000040064d <+0>:     push   %rbp
   0x000000000040064e <+1>:     mov    %rsp,%rbp
   0x0000000000400651 <+4>:     sub    $0x10,%rsp
=> 0x0000000000400655 <+8>:     movq   $0x0,-0x8(%rbp)
   0x000000000040065d <+16>:    movl   $0x18,-0xc(%rbp)
   0x0000000000400664 <+23>:    mov    $0x400770,%edi
   0x0000000000400669 <+28>:    callq  0x400500 <puts@plt>
   0x000000000040066e <+33>:    mov    $0x18,%esi
   0x0000000000400673 <+38>:    mov    $0x400783,%edi
   0x0000000000400678 <+43>:    mov    $0x0,%eax
   0x000000000040067d <+48>:    callq  0x400510 <printf@plt>
   0x0000000000400682 <+53>:    mov    -0xc(%rbp),%eax
   0x0000000000400685 <+56>:    cltq
   0x0000000000400687 <+58>:    mov    %rax,%rdi
   0x000000000040068a <+61>:    callq  0x400550 <malloc@plt>
   0x000000000040068f <+66>:    mov    %rax,-0x8(%rbp)
   0x0000000000400693 <+70>:    mov    -0xc(%rbp),%eax
   0x0000000000400696 <+73>:    movslq %eax,%rdx
   0x0000000000400699 <+76>:    mov    -0x8(%rbp),%rax
   0x000000000040069d <+80>:    mov    $0x0,%esi
   0x00000000004006a2 <+85>:    mov    %rax,%rdi
   0x00000000004006a5 <+88>:    callq  0x400520 <memset@plt>
   0x00000000004006aa <+93>:    mov    -0x8(%rbp),%rax
   0x00000000004006ae <+97>:    movq   $0x6f,(%rax)
   0x00000000004006b5 <+104>:   mov    -0x8(%rbp),%rax
   0x00000000004006b9 <+108>:   movq   $0xde,0x8(%rax)
   0x00000000004006c1 <+116>:   mov    -0x8(%rbp),%rax
   0x00000000004006c5 <+120>:   movq   $0x14d,0x10(%rax)
   0x00000000004006cd <+128>:   mov    -0x8(%rbp),%rax
   0x00000000004006d1 <+132>:   mov    %rax,%rdi
   0x00000000004006d4 <+135>:   callq  0x4004f0 <free@plt>
   0x00000000004006d9 <+140>:   mov    $0x0,%eax
   0x00000000004006de <+145>:   leaveq
   0x00000000004006df <+146>:   retq
End of assembler dump.

Используя определенную строку кода, точка останова устанавливается свободной.

(gdb) break *0x00000000004006d4

Продолжайте до тех пор, пока код на команду free не нарушится.

(gdb) continue
Continuing.
Size of (bytes)...
     myStruct : 24

Breakpoint 2, 0x00000000004006d4 in main () at freeQuestion.c:28
28         free(p_Struct);

Отображение доступных регистров.

(gdb) info reg
rax            0x602010 6299664
rbx            0x0      0
rcx            0x602010 6299664
rdx            0x18     24
rsi            0x0      0
rdi            0x602010 6299664
rbp            0x7fffffffc160   0x7fffffffc160
rsp            0x7fffffffc150   0x7fffffffc150
r8             0x602000 6299648
r9             0x18     24
r10            0x7fffffffbed0   140737488338640
r11            0x2aaaaad56700   46912498919168
r12            0x400560 4195680
r13            0x7fffffffc240   140737488339520
r14            0x0      0
r15            0x0      0
rip            0x4006d4 0x4006d4 <main+135>
eflags         0x283    [ CF SF IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb)

Я предполагаю, что в регистре rdi будут храниться данные, которые освобождаются по адресу 0x602010.Чтобы убедиться, что все данные будут видны, команда проверки выполняется для отображения 80 байтов данных, начинающихся с 16 байтов ранее.

(gdb) x/80d 0x602000
0x602000:       0       0       0       0       0       0       0       0
0x602008:       33      0       0       0       0       0       0       0
0x602010:       111     0       0       0       0       0       0       0
0x602018:       -34     0       0       0       0       0       0       0
0x602020:       77      1       0       0       0       0       0       0
0x602028:       -31     15      2       0       0       0       0       0
0x602030:       0       0       0       0       0       0       0       0
0x602038:       0       0       0       0       0       0       0       0
0x602040:       0       0       0       0       0       0       0       0
0x602048:       0       0       0       0       0       0       0       0
(gdb)

Из приведенного выше 111 виден, но не 222 или 333.

Как можно просмотреть все данные (111,222,333) до выполнения свободной команды?

1 Ответ

0 голосов
/ 16 октября 2018

Из вышесказанного, 111 виден, но не 222 или 333.

Существует нет способ, которым вы могли бы наблюдать этот выход при остановке доCALL free инструкция.Мы ясно видим, что значения 0x6f == 111, 0xde == 222 и 0x14d == 333 загружаются со смещением 0, 8 и 16 от $RAX:

0x00000000004006ae <+97>:    movq   $0x6f,(%rax)
0x00000000004006b9 <+108>:   movq   $0xde,0x8(%rax)
0x00000000004006c5 <+120>:   movq   $0x14d,0x10(%rax)

, а затем $RAX копируется в $RDIнезадолго до вызова free:

0x00000000004006d1 <+132>:   mov    %rax,%rdi
0x00000000004006d4 <+135>:   callq  0x4004f0 <free@plt>

Вот ожидаемый результат (который я наблюдаю с вашей программой):

(gdb) p/x $rdi
$1 = 0x602420

(gdb) x/6d $rdi
0x602420:   111 0   222 0
0x602430:   333 0

Но если вы выполните nexti (дляперешагните вызов free), тогда значения могут быть перезаписаны (вы не можете ожидать, что содержимое free d памяти будет что-нибудь в частности).

После nexti я наблюдаю:

(gdb) x/6d 0x602420
0x602420:   0   0   222 0
0x602430:   333 0

, но это может быть просто 111 0 0 0 0 0, что вы наблюдали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...