日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > 《coredump問題原理探究》Linux x86版6.4節(jié)虛函數(shù)

《coredump問題原理探究》Linux x86版6.4節(jié)虛函數(shù)

來源:程序員人生   發(fā)布時(shí)間:2015-03-02 08:42:22 閱讀次數(shù):3179次

在上1節(jié)已探究了類的成員變量的排列,現(xiàn)在看1下虛函數(shù)表和成員變量的排列及虛函數(shù)之間的排列.

先看1個(gè)例子:

1 #include <stdio.h> 2 class xuzhina_dump_c06_s3 3 { 4 private: 5 int m_a; 6 public: 7 xuzhina_dump_c06_s3() { m_a = 0; } 8 virtual void inc() { m_a++; } 9 virtual void dec() { m_a--; } 10 virtual void print() 11 { 12 printf( "%d ", m_a ); 13 } 14 }; 15 16 int main() 17 { 18 xuzhina_dump_c06_s3* test = new xuzhina_dump_c06_s3; 19 if ( test != NULL ) 20 { 21 test->inc(); 22 test->inc(); 23 test->print(); 24 } 25 return 0; 26 }

匯編代碼:

(gdb) disassemble main Dump of assembler code for function main: 0x08048560 <+0>: push %ebp 0x08048561 <+1>: mov %esp,%ebp 0x08048563 <+3>: push %ebx 0x08048564 <+4>: and $0xfffffff0,%esp 0x08048567 <+7>: sub $0x20,%esp 0x0804856a <+10>: movl $0x8,(%esp) 0x08048571 <+17>: call 0x8048450 <_Znwj@plt> 0x08048576 <+22>: mov %eax,%ebx 0x08048578 <+24>: mov %ebx,(%esp) 0x0804857b <+27>: call 0x80485cc <_ZN19xuzhina_dump_c06_s3C2Ev> 0x08048580 <+32>: mov %ebx,0x1c(%esp) 0x08048584 <+36>: cmpl $0x0,0x1c(%esp) 0x08048589 <+41>: je 0x80485c1 <main+97> 0x0804858b <+43>: mov 0x1c(%esp),%eax 0x0804858f <+47>: mov (%eax),%eax 0x08048591 <+49>: mov (%eax),%eax 0x08048593 <+51>: mov 0x1c(%esp),%edx 0x08048597 <+55>: mov %edx,(%esp) 0x0804859a <+58>: call *%eax 0x0804859c <+60>: mov 0x1c(%esp),%eax 0x080485a0 <+64>: mov (%eax),%eax 0x080485a2 <+66>: mov (%eax),%eax 0x080485a4 <+68>: mov 0x1c(%esp),%edx 0x080485a8 <+72>: mov %edx,(%esp) 0x080485ab <+75>: call *%eax 0x080485ad <+77>: mov 0x1c(%esp),%eax 0x080485b1 <+81>: mov (%eax),%eax 0x080485b3 <+83>: add $0x8,%eax 0x080485b6 <+86>: mov (%eax),%eax 0x080485b8 <+88>: mov 0x1c(%esp),%edx 0x080485bc <+92>: mov %edx,(%esp) 0x080485bf <+95>: call *%eax 0x080485c1 <+97>: mov $0x0,%eax 0x080485c6 <+102>: mov -0x4(%ebp),%ebx 0x080485c9 <+105>: leave 0x080485ca <+106>: ret End of assembler dump.

由上面代碼可知,履行完了構(gòu)造函數(shù),test的m_a的值,會(huì)變成0。且由上面匯編可以看到this指針在調(diào)用構(gòu)造函數(shù)前后,是放在ebx寄存器。

在0x08048578,0x08048580都打斷點(diǎn),看1下this指針?biāo)赶虻牡刂肥欠袷沁@樣的結(jié)果。

(gdb) tbreak *0x08048578 Temporary breakpoint 1 at 0x8048578 (gdb) tbreak *0x08048580 Temporary breakpoint 2 at 0x8048580 (gdb) r Starting program: /home/buckxu/work/6/3/xuzhina_dump_c6_s3 Temporary breakpoint 1, 0x08048578 in main () (gdb) x /4x $ebx 0x804a008: 0x00000000 0x00000000 0x00000000 0x00020ff1 (gdb) c Continuing. Temporary breakpoint 2, 0x08048580 in main () (gdb) x /4x $ebx 0x804a008: 0x080486d0 0x00000000 0x00000000 0x00020ff1

非常奇怪,依照上1節(jié)的內(nèi)容,地址0x804a008應(yīng)當(dāng)寄存m_a,會(huì)初始化為0.究竟類xuzhina_dump_c06_s3的構(gòu)造函數(shù)做了甚么事情?而0x080486d0是甚么東西來的?

看1下類xuzhina_dump_c06_s3的構(gòu)造函數(shù):

(gdb) disassemble _ZN19xuzhina_dump_c06_s3C2Ev Dump of assembler code for function _ZN19xuzhina_dump_c06_s3C2Ev: 0x080485cc <+0>: push %ebp 0x080485cd <+1>: mov %esp,%ebp 0x080485cf <+3>: mov 0x8(%ebp),%eax 0x080485d2 <+6>: movl $0x80486d0,(%eax) 0x080485d8 <+12>: mov 0x8(%ebp),%eax 0x080485db <+15>: movl $0x0,0x4(%eax) 0x080485e2 <+22>: pop %ebp 0x080485e3 <+23>: ret End of assembler dump.

由構(gòu)造函數(shù)的匯編可知,0x80486d0這個(gè)值是在構(gòu)造函數(shù)設(shè)置,但還不清楚是甚么東西。而

0x080485d8 <+12>: mov 0x8(%ebp),%eax 0x080485db <+15>: movl $0x0,0x4(%eax)

卻恰好對(duì)應(yīng)了

7 xuzhina_dump_c06_s3() { m_a = 0; }

也就是說,類xuzhina_dump_c06_s3的第1個(gè)成員變量m_a放在偏移this指針的地方,那末0x80486d0是甚么東西,占了m_a的位置呢?

重新看1下main函數(shù)的匯編:

(gdb) disassemble main Dump of assembler code for function main: 0x08048560 <+0>: push %ebp 0x08048561 <+1>: mov %esp,%ebp 0x08048563 <+3>: push %ebx 0x08048564 <+4>: and $0xfffffff0,%esp 0x08048567 <+7>: sub $0x20,%esp 0x0804856a <+10>: movl $0x8,(%esp) 0x08048571 <+17>: call 0x8048450 <_Znwj@plt> 0x08048576 <+22>: mov %eax,%ebx 0x08048578 <+24>: mov %ebx,(%esp) 0x0804857b <+27>: call 0x80485cc <_ZN19xuzhina_dump_c06_s3C2Ev> => 0x08048580 <+32>: mov %ebx,0x1c(%esp) 0x08048584 <+36>: cmpl $0x0,0x1c(%esp) 0x08048589 <+41>: je 0x80485c1 <main+97> 0x0804858b <+43>: mov 0x1c(%esp),%eax 0x0804858f <+47>: mov (%eax),%eax 0x08048591 <+49>: mov (%eax),%eax 0x08048593 <+51>: mov 0x1c(%esp),%edx 0x08048597 <+55>: mov %edx,(%esp) 0x0804859a <+58>: call *%eax 0x0804859c <+60>: mov 0x1c(%esp),%eax 0x080485a0 <+64>: mov (%eax),%eax 0x080485a2 <+66>: mov (%eax),%eax 0x080485a4 <+68>: mov 0x1c(%esp),%edx 0x080485a8 <+72>: mov %edx,(%esp) 0x080485ab <+75>: call *%eax 0x080485ad <+77>: mov 0x1c(%esp),%eax 0x080485b1 <+81>: mov (%eax),%eax 0x080485b3 <+83>: add $0x8,%eax 0x080485b6 <+86>: mov (%eax),%eax 0x080485b8 <+88>: mov 0x1c(%esp),%edx 0x080485bc <+92>: mov %edx,(%esp) 0x080485bf <+95>: call *%eax 0x080485c1 <+97>: mov $0x0,%eax 0x080485c6 <+102>: mov -0x4(%ebp),%ebx 0x080485c9 <+105>: leave 0x080485ca <+106>: ret End of assembler dump.

0x0804857b <+27>: call 0x80485cc <_ZN19xuzhina_dump_c06_s3C2Ev> 0x08048580 <+32>: mov %ebx,0x1c(%esp)

可知,esp+0x1c用來寄存this指針。

再看1下這幾段指令:

0x0804858b <+43>: mov 0x1c(%esp),%eax 0x0804858f <+47>: mov (%eax),%eax 0x08048591 <+49>: mov (%eax),%eax 0x08048593 <+51>: mov 0x1c(%esp),%edx 0x08048597 <+55>: mov %edx,(%esp) 0x0804859a <+58>: call *%eax 0x0804859c <+60>: mov 0x1c(%esp),%eax 0x080485a0 <+64>: mov (%eax),%eax 0x080485a2 <+66>: mov (%eax),%eax 0x080485a4 <+68>: mov 0x1c(%esp),%edx 0x080485a8 <+72>: mov %edx,(%esp) 0x080485ab <+75>: call *%eax 0x080485ad <+77>: mov 0x1c(%esp),%eax 0x080485b1 <+81>: mov (%eax),%eax 0x080485b3 <+83>: add $0x8,%eax 0x080485b6 <+86>: mov (%eax),%eax 0x080485b8 <+88>: mov 0x1c(%esp),%edx 0x080485bc <+92>: mov %edx,(%esp) 0x080485bf <+95>: call *%eax

由因而順序結(jié)構(gòu),可知,這3段指令恰好對(duì)應(yīng)

21 test->inc(); 22 test->inc(); 23 test->print();

分析1下第3段匯編:

0x080485ad <+77>: mov 0x1c(%esp),%eax 0x080485b1 <+81>: mov (%eax),%eax 0x080485b3 <+83>: add $0x8,%eax 0x080485b6 <+86>: mov (%eax),%eax 0x080485b8 <+88>: mov 0x1c(%esp),%edx 0x080485bc <+92>: mov %edx,(%esp) 0x080485bf <+95>: call *%eax

可見eax正好是放著print這個(gè)虛函數(shù)的指針。而這個(gè)指針終究是由esp+0x1c來獲得。由

0x080485ad <+77>: mov 0x1c(%esp),%eax 0x080485b1 <+81>: mov (%eax),%eax

可知,正好是從this指針的第1個(gè)成員取出來的,也就是說,這個(gè)成員是虛函數(shù)表指針。根據(jù)上面的分析,可知這個(gè)虛函數(shù)表指針的值是0x80486d0。來驗(yàn)證1下,它是否是虛函數(shù)表指針。

(gdb) x /4x 0x80486d0 0x80486d0 <_ZTV19xuzhina_dump_c06_s3+8>: 0x080485e4 0x080485f8 0x0804860c 0x75783931 (gdb) shell c++filt _ZTV19xuzhina_dump_c06_s3 vtable for xuzhina_dump_c06_s3 (gdb) info symbol 0x080485e4 xuzhina_dump_c06_s3::inc() in section .text of /home/buckxu/work/6/3/xuzhina_dump_c6_s3 (gdb) info symbol 0x080485f8 xuzhina_dump_c06_s3::dec() in section .text of /home/buckxu/work/6/3/xuzhina_dump_c6_s3 (gdb) info symbol 0x0804860c xuzhina_dump_c06_s3::print() in section .text of /home/buckxu/work/6/3/xuzhina_dump_c6_s3

可見,0x80486d0所指向正是虛函數(shù)表,且里面的表項(xiàng)順序正好和虛函數(shù)的聲明順序1樣。

 

由上面分析,test所指向的對(duì)象的內(nèi)存布局以下圖:


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 免费99视频| 国产欧美一区二区视频 | 日韩不卡免费视频 | a在线免费观看 | 欧美精品一区视频 | 国产成人精品免费视频 | 欧美色图片一区二区 | www一区二区| 黄色小视频在线免费观看 | 中文字幕在线免费看 | 中国av大片 | 国产精品美女久久久久aⅴ国产馆 | 操操操av| 在线欧美日韩国产 | 久9re热视频这里只有精品 | 亚洲精品久久久久 | 国产精品亚洲视频 | 91久久久久久久 | 成人黄色免费网站 | 一区二区三区久久久 | 爱爱网址 | 国产精品久久久久久久久久久久久 | 国产一区二区影院 | 麻豆av在线播放 | 国产精品成人3p一区二区三区 | 日韩精品一区在线 | a亚洲天堂 | 黄片毛片在线观看 | 久久久网站免费 | 国产一区导航 | 国产伦精品一区 | 一级片大全 | 欧美激情视频在线播放 | 看免费黄色一级片 | 一区二区三区在线观看国产 | 国产一区二区三区精品在线观看 | 久久6热视频 | 日韩av在线不卡 | 日韩欧美综合在线视频 | 天天射天天射天天射 | 三级欧美 |