gdb如何转储结构的数据?

gdb如何转储结构的数据?,gdb,Gdb,使用一个非常简单的示例,该示例使用int指针指向具有long的结构。虽然它不是首选方法,但它是为了模仿其他代码而进行的。目的是在免费通话前查看寄存器中的数据 这是代码 #include <stdio.h> #include <stdlib.h> //#include <unistd.h> typedef struct { unsigned long x; unsigned long y;

使用一个非常简单的示例,该示例使用int指针指向具有long的结构。虽然它不是首选方法,但它是为了模仿其他代码而进行的。目的是在免费通话前查看寄存器中的数据

这是代码

#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);
 }
继续,直到free命令上的代码中断

(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) 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)
从上面看,111是可见的,但不是222或333

在执行自由命令之前,如何查看所有数据(111222333)

从上面看,111是可见的,但不是222或333

无呼叫
指令之前停止时,您不可能观察到此输出。我们清楚地看到,值
0x6f==111
0xde==222
0x14d==333
$RAX
的偏移量0、8和16处加载:

0x00000000004006ae <+97>:    movq   $0x6f,(%rax)
0x00000000004006b9 <+108>:   movq   $0xde,0x8(%rax)
0x00000000004006c5 <+120>:   movq   $0x14d,0x10(%rax)
以下是预期输出(我在您的程序中观察到):

但是如果执行
nexti
(跳过对
free
的调用),则可以覆盖这些值(您不能期望now
free
d内存的内容是任何特定的内容)

nexti
之后,我观察到:

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

但是你观察到的结果也可能是
111 0 0 0

谢谢。两条评论。您提到“我们清楚地看到值0x6f==111、0xde==222和0x14d==333在$EAX的偏移量0、8和16处加载,然后$EAX被复制到$RDI”,但您能否澄清一下,因为我看不清楚。第二,我回顾了代码,我看到了上面的内容。我昨天运行了多次,无法解释为什么会得到不同的结果。@UnhandledException我已经更新了答案。对于“两个”--我只能猜测您是在运行
0x4006b9
的指令之前,还是在
0x4006d4
调用之后查看的。啊,现在我看到了。对EAX的引用让我有点不舒服,但假设它应该是RAX。正如注释“…然后$EAX被复制到$RDI,就在调用free之前:”对我来说似乎是RAX到RDI。再次感谢你澄清这一点。
0x00000000004006ae <+97>:    movq   $0x6f,(%rax)
0x00000000004006b9 <+108>:   movq   $0xde,0x8(%rax)
0x00000000004006c5 <+120>:   movq   $0x14d,0x10(%rax)
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
(gdb) x/6d 0x602420
0x602420:   0   0   222 0
0x602430:   333 0