本文主要是学习coredump中构造函数的分析主要分析以下两点
- 反编译的构造函数;
- 汇编中构造函数的内存结构
随便写一个类,使用的g++ -g -o this.cpp mythis
#include <stdio.h>
class xuzhia_dump_c06_s2
{
private:
short m_c;
char m_d;
int m_e;
public:
xuzhia_dump_c06_s2(int a,int b){
m_c = (short)(a+b);
m_d = 'd';
m_e = a -b;
}
void print(){
printf("mem %d,%c,%d\n",m_c,m_d,m_e);
}
};
int main(){
xuzhia_dump_c06_s2 test(2,3);
test.print();
return 0;
}
生成一个mythis
gdb 跑起来先反编译main:
(gdb) disassemble main
Dump of assembler code for function main():
0x0000000000400596 <+0>: push %rbp
0x0000000000400597 <+1>: mov %rsp,%rbp
0x000000000040059a <+4>: sub $0x10,%rsp
0x000000000040059e <+8>: mov %fs:0x28,%rax
0x00000000004005a7 <+17>: mov %rax,-0x8(%rbp)
0x00000000004005ab <+21>: xor %eax,%eax
0x00000000004005ad <+23>: lea -0x10(%rbp),%rax
0x00000000004005b1 <+27>: mov $0x3,%edx//参数1
0x00000000004005b6 <+32>: mov $0x2,%esi//参数2
0x00000000004005bb <+37>: mov %rax,%rdi//参赛3
0x00000000004005be <+40>: callq 0x4005ea <xuzhia_dump_c06_s2::xuzhia_dump_c06_s2(int, int)>
0x00000000004005c3 <+45>: lea -0x10(%rbp),%rax
0x00000000004005c7 <+49>: mov %rax,%rdi
0x00000000004005ca <+52>: callq 0x400626 <xuzhia_dump_c06_s2::print()>
0x00000000004005cf <+57>: mov $0x0,%eax
0x00000000004005d4 <+62>: mov -0x8(%rbp),%rcx
0x00000000004005d8 <+66>: xor %fs:0x28,%rcx
0x00000000004005e1 <+75>: je 0x4005e8 <main()+82>
0x00000000004005e3 <+77>: callq 0x400460 <__stack_chk_fail@plt>
0x00000000004005e8 <+82>: leaveq
这里要说下参数3,根据协议参数1和参数2比较好理解,但参数3是什么,参数3就是this指针,大家知道在c++构造函数中会有一个默认的参数this,就是这个,而在协议中rax这个寄存器是存放返回值的。在接着看汇编,下面做的事情是调用构造函数,结合简单的汇编可以得出在汇编的构造函数中会将构造函数的结果保存在rax中,这个rax就是this指针。
在来看下构造函数里面变量的内存结构
在对应的地方打点
(gdb) b 19
Breakpoint 1 at 0x4005ad: file this.cpp, line 19.
(gdb) b 20
Breakpoint 2 at 0x4005c3: file this.cpp, line 20.
(gdb) b main+45
Function "main+45" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 3 (main+45) pending.
(gdb) run
Starting program: /home/open/vm/coredump/mythis
Breakpoint 1, main () at this.cpp:19
19 xuzhia_dump_c06_s2 test(2,3);
(gdb) n
Breakpoint 2, main () at this.cpp:20
20 test.print();
在运行到20时候即构造函数构造完成之后看下rax里面的值
(gdb) info registers
rax 0x7fffffffdd00 140737488346368
rbx 0x0 0
rcx 0x0 0
rdx 0xffffffff 4294967295
rsi 0x2 2
rdi 0x7fffffffdd00 140737488346368
rbp 0x7fffffffdd10 0x7fffffffdd10
打印下rax里面的地址值
(gdb) x/3uh 0x7fffffffdd00
0x7fffffffdd00: 5 65380 65535
可以看到构造函数里面的内存结构,这个和 5 'd' -1对应。