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