前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《coredump问题原理探究》Linux x86版7.6节 Map coredump例子

《coredump问题原理探究》Linux x86版7.6节 Map coredump例子

作者头像
血狼debugeeker
发布2018-09-20 14:42:32
1.4K0
发布2018-09-20 14:42:32
举报
文章被收录于专栏:debugeeker的专栏debugeeker的专栏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344535

定位一个map相关的coredump来熟悉一下:

代码语言:javascript
复制
Core was generated by `./xuzhina_dump_c07_s3_ex 5 / 6'.
Program terminated with signal 11, Segmentation fault.
#0  0x00000000 in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.4.i686 libgcc-4.4.7-11.el6.i686 libstdc++-4.4.7-11.el6.i686
(gdb) bt
#0  0x00000000 in ?? ()
#1  0x08048bd0 in main ()
(gdb) i r 
eax            0x5	5
ecx            0x0	0
edx            0x0	0
ebx            0x6	6
esp            0xbfd3de7c	0xbfd3de7c
ebp            0xbfd3dee8	0xbfd3dee8
esi            0x0	0
edi            0x0	0
eip            0x0	0
eflags         0x210296	[ PF AF SF IF RF ID ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51

由于栈顶的指令地址为0x0,而eip的值也是0x0,可以知道是调用了函数指针,且函数指针的值为空.而这个函数指针是由main函数调用

看一下main函数的汇编:

代码语言:javascript
复制
(gdb) disassemble 
Dump of assembler code for function main:
   0x0804898f <+0>:	push   %ebp
   0x08048990 <+1>:	mov    %esp,%ebp
   0x08048992 <+3>:	and    $0xfffffff0,%esp
   0x08048995 <+6>:	push   %esi
   0x08048996 <+7>:	push   %ebx
   0x08048997 <+8>:	sub    $0x58,%esp
   0x0804899a <+11>:	cmpl   $0x3,0x8(%ebp)
   0x0804899e <+15>:	jg     0x80489b6 <main+39>
   0x080489a0 <+17>:	movl   $0x8049ce4,(%esp)
   0x080489a7 <+24>:	call   0x804883c <puts@plt>
   0x080489ac <+29>:	mov    $0xffffffff,%ebx
   0x080489b1 <+34>:	jmp    0x8048c42 <main+691>
   0x080489b6 <+39>:	lea    0x18(%esp),%eax
   0x080489ba <+43>:	mov    %eax,(%esp)
   0x080489bd <+46>:	call   0x8048c6e <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEC2Ev>
   0x080489c2 <+51>:	lea    0x37(%esp),%eax
   0x080489c6 <+55>:	mov    %eax,(%esp)
   0x080489c9 <+58>:	call   0x804887c <_ZNSaIcEC1Ev@plt>
   0x080489ce <+63>:	lea    0x37(%esp),%eax
   0x080489d2 <+67>:	mov    %eax,0x8(%esp)
   0x080489d6 <+71>:	movl   $0x8049cfa,0x4(%esp)
---Type <return> to continue, or q <return> to quit---
   0x080489de <+79>:	lea    0x30(%esp),%eax
   0x080489e2 <+83>:	mov    %eax,(%esp)
   0x080489e5 <+86>:	call   0x80487ec <_ZNSsC1EPKcRKSaIcE@plt>
   0x080489ea <+91>:	lea    0x30(%esp),%eax
   0x080489ee <+95>:	mov    %eax,0x4(%esp)
   0x080489f2 <+99>:	lea    0x18(%esp),%eax
   0x080489f6 <+103>:	mov    %eax,(%esp)
   0x080489f9 <+106>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x080489fe <+111>:	movl   $0x8048964,(%eax)
   0x08048a04 <+117>:	lea    0x30(%esp),%eax
   0x08048a08 <+121>:	mov    %eax,(%esp)
   0x08048a0b <+124>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048a10 <+129>:	jmp    0x8048a41 <main+178>
   0x08048a12 <+131>:	mov    %edx,%ebx
   0x08048a14 <+133>:	mov    %eax,%esi
   0x08048a16 <+135>:	lea    0x30(%esp),%eax
   0x08048a1a <+139>:	mov    %eax,(%esp)
   0x08048a1d <+142>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048a22 <+147>:	mov    %esi,%eax
   0x08048a24 <+149>:	mov    %ebx,%edx
   0x08048a26 <+151>:	jmp    0x8048a28 <main+153>
   0x08048a28 <+153>:	mov    %edx,%ebx
---Type <return> to continue, or q <return> to quit---
   0x08048a2a <+155>:	mov    %eax,%esi
   0x08048a2c <+157>:	lea    0x37(%esp),%eax
   0x08048a30 <+161>:	mov    %eax,(%esp)
   0x08048a33 <+164>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048a38 <+169>:	mov    %esi,%eax
   0x08048a3a <+171>:	mov    %ebx,%edx
   0x08048a3c <+173>:	jmp    0x8048c26 <main+663>
   0x08048a41 <+178>:	lea    0x37(%esp),%eax
   0x08048a45 <+182>:	mov    %eax,(%esp)
   0x08048a48 <+185>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048a4d <+190>:	lea    0x3f(%esp),%eax
   0x08048a51 <+194>:	mov    %eax,(%esp)
   0x08048a54 <+197>:	call   0x804887c <_ZNSaIcEC1Ev@plt>
   0x08048a59 <+202>:	lea    0x3f(%esp),%eax
   0x08048a5d <+206>:	mov    %eax,0x8(%esp)
   0x08048a61 <+210>:	movl   $0x8049cfc,0x4(%esp)
   0x08048a69 <+218>:	lea    0x38(%esp),%eax
   0x08048a6d <+222>:	mov    %eax,(%esp)
   0x08048a70 <+225>:	call   0x80487ec <_ZNSsC1EPKcRKSaIcE@plt>
   0x08048a75 <+230>:	lea    0x38(%esp),%eax
   0x08048a79 <+234>:	mov    %eax,0x4(%esp)
   0x08048a7d <+238>:	lea    0x18(%esp),%eax
   0x08048a81 <+242>:	mov    %eax,(%esp)
---Type <return> to continue, or q <return> to quit---
   0x08048a84 <+245>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048a89 <+250>:	movl   $0x8048972,(%eax)
   0x08048a8f <+256>:	lea    0x38(%esp),%eax
   0x08048a93 <+260>:	mov    %eax,(%esp)
   0x08048a96 <+263>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048a9b <+268>:	jmp    0x8048acc <main+317>
   0x08048a9d <+270>:	mov    %edx,%ebx
   0x08048a9f <+272>:	mov    %eax,%esi
   0x08048aa1 <+274>:	lea    0x38(%esp),%eax
   0x08048aa5 <+278>:	mov    %eax,(%esp)
   0x08048aa8 <+281>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048aad <+286>:	mov    %esi,%eax
   0x08048aaf <+288>:	mov    %ebx,%edx
   0x08048ab1 <+290>:	jmp    0x8048ab3 <main+292>
   0x08048ab3 <+292>:	mov    %edx,%ebx
   0x08048ab5 <+294>:	mov    %eax,%esi
   0x08048ab7 <+296>:	lea    0x3f(%esp),%eax
   0x08048abb <+300>:	mov    %eax,(%esp)
   0x08048abe <+303>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048ac3 <+308>:	mov    %esi,%eax
   0x08048ac5 <+310>:	mov    %ebx,%edx
   0x08048ac7 <+312>:	jmp    0x8048c26 <main+663>
---Type <return> to continue, or q <return> to quit---
   0x08048acc <+317>:	lea    0x3f(%esp),%eax
   0x08048ad0 <+321>:	mov    %eax,(%esp)
   0x08048ad3 <+324>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048ad8 <+329>:	lea    0x47(%esp),%eax
   0x08048adc <+333>:	mov    %eax,(%esp)
   0x08048adf <+336>:	call   0x804887c <_ZNSaIcEC1Ev@plt>
   0x08048ae4 <+341>:	lea    0x47(%esp),%eax
   0x08048ae8 <+345>:	mov    %eax,0x8(%esp)
   0x08048aec <+349>:	movl   $0x8049cfe,0x4(%esp)
   0x08048af4 <+357>:	lea    0x40(%esp),%eax
   0x08048af8 <+361>:	mov    %eax,(%esp)
   0x08048afb <+364>:	call   0x80487ec <_ZNSsC1EPKcRKSaIcE@plt>
   0x08048b00 <+369>:	lea    0x40(%esp),%eax
   0x08048b04 <+373>:	mov    %eax,0x4(%esp)
   0x08048b08 <+377>:	lea    0x18(%esp),%eax
   0x08048b0c <+381>:	mov    %eax,(%esp)
   0x08048b0f <+384>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048b14 <+389>:	movl   $0x8048983,(%eax)
   0x08048b1a <+395>:	lea    0x40(%esp),%eax
   0x08048b1e <+399>:	mov    %eax,(%esp)
   0x08048b21 <+402>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048b26 <+407>:	jmp    0x8048b57 <main+456>
---Type <return> to continue, or q <return> to quit---
   0x08048b28 <+409>:	mov    %edx,%ebx
   0x08048b2a <+411>:	mov    %eax,%esi
   0x08048b2c <+413>:	lea    0x40(%esp),%eax
   0x08048b30 <+417>:	mov    %eax,(%esp)
   0x08048b33 <+420>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048b38 <+425>:	mov    %esi,%eax
   0x08048b3a <+427>:	mov    %ebx,%edx
   0x08048b3c <+429>:	jmp    0x8048b3e <main+431>
   0x08048b3e <+431>:	mov    %edx,%ebx
   0x08048b40 <+433>:	mov    %eax,%esi
   0x08048b42 <+435>:	lea    0x47(%esp),%eax
   0x08048b46 <+439>:	mov    %eax,(%esp)
   0x08048b49 <+442>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048b4e <+447>:	mov    %esi,%eax
   0x08048b50 <+449>:	mov    %ebx,%edx
   0x08048b52 <+451>:	jmp    0x8048c26 <main+663>
   0x08048b57 <+456>:	lea    0x47(%esp),%eax
   0x08048b5b <+460>:	mov    %eax,(%esp)
   0x08048b5e <+463>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048b63 <+468>:	lea    0x4f(%esp),%eax
   0x08048b67 <+472>:	mov    %eax,(%esp)
   0x08048b6a <+475>:	call   0x804887c <_ZNSaIcEC1Ev@plt>
   0x08048b6f <+480>:	mov    0xc(%ebp),%eax
---Type <return> to continue, or q <return> to quit---
   0x08048b72 <+483>:	add    $0x8,%eax
   0x08048b75 <+486>:	mov    (%eax),%eax
   0x08048b77 <+488>:	lea    0x4f(%esp),%edx
   0x08048b7b <+492>:	mov    %edx,0x8(%esp)
   0x08048b7f <+496>:	mov    %eax,0x4(%esp)
   0x08048b83 <+500>:	lea    0x48(%esp),%eax
   0x08048b87 <+504>:	mov    %eax,(%esp)
   0x08048b8a <+507>:	call   0x80487ec <_ZNSsC1EPKcRKSaIcE@plt>
   0x08048b8f <+512>:	lea    0x48(%esp),%eax
   0x08048b93 <+516>:	mov    %eax,0x4(%esp)
   0x08048b97 <+520>:	lea    0x18(%esp),%eax
   0x08048b9b <+524>:	mov    %eax,(%esp)
   0x08048b9e <+527>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048ba3 <+532>:	mov    (%eax),%esi
   0x08048ba5 <+534>:	mov    0xc(%ebp),%eax
   0x08048ba8 <+537>:	add    $0xc,%eax
   0x08048bab <+540>:	mov    (%eax),%eax
   0x08048bad <+542>:	mov    %eax,(%esp)
   0x08048bb0 <+545>:	call   0x80487fc <atoi@plt>
   0x08048bb5 <+550>:	mov    %eax,%ebx
   0x08048bb7 <+552>:	mov    0xc(%ebp),%eax
   0x08048bba <+555>:	add    $0x4,%eax
---Type <return> to continue, or q <return> to quit---
   0x08048bbd <+558>:	mov    (%eax),%eax
   0x08048bbf <+560>:	mov    %eax,(%esp)
   0x08048bc2 <+563>:	call   0x80487fc <atoi@plt>
   0x08048bc7 <+568>:	mov    %ebx,0x4(%esp)
   0x08048bcb <+572>:	mov    %eax,(%esp)
   0x08048bce <+575>:	call   *%esi
=> 0x08048bd0 <+577>:	mov    %eax,%ebx
   0x08048bd2 <+579>:	lea    0x48(%esp),%eax
   0x08048bd6 <+583>:	mov    %eax,(%esp)
   0x08048bd9 <+586>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048bde <+591>:	jmp    0x8048c0c <main+637>
   0x08048be0 <+593>:	mov    %edx,%ebx
   0x08048be2 <+595>:	mov    %eax,%esi
   0x08048be4 <+597>:	lea    0x48(%esp),%eax
   0x08048be8 <+601>:	mov    %eax,(%esp)
   0x08048beb <+604>:	call   0x80487cc <_ZNSsD1Ev@plt>
   0x08048bf0 <+609>:	mov    %esi,%eax
   0x08048bf2 <+611>:	mov    %ebx,%edx
   0x08048bf4 <+613>:	jmp    0x8048bf6 <main+615>
   0x08048bf6 <+615>:	mov    %edx,%ebx
   0x08048bf8 <+617>:	mov    %eax,%esi
   0x08048bfa <+619>:	lea    0x4f(%esp),%eax
   0x08048bfe <+623>:	mov    %eax,(%esp)
   0x08048c01 <+626>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048c06 <+631>:	mov    %esi,%eax
   0x08048c08 <+633>:	mov    %ebx,%edx
   0x08048c0a <+635>:	jmp    0x8048c26 <main+663>
   0x08048c0c <+637>:	lea    0x4f(%esp),%eax
   0x08048c10 <+641>:	mov    %eax,(%esp)
   0x08048c13 <+644>:	call   0x804882c <_ZNSaIcED1Ev@plt>
   0x08048c18 <+649>:	lea    0x18(%esp),%eax
   0x08048c1c <+653>:	mov    %eax,(%esp)
   0x08048c1f <+656>:	call   0x8048c5a <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEED2Ev>
   0x08048c24 <+661>:	jmp    0x8048c42 <main+691>
   0x08048c26 <+663>:	mov    %edx,%ebx
   0x08048c28 <+665>:	mov    %eax,%esi
   0x08048c2a <+667>:	lea    0x18(%esp),%eax
   0x08048c2e <+671>:	mov    %eax,(%esp)
   0x08048c31 <+674>:	call   0x8048c5a <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEED2Ev>
   0x08048c36 <+679>:	mov    %esi,%eax
   0x08048c38 <+681>:	mov    %ebx,%edx
   0x08048c3a <+683>:	mov    %eax,(%esp)
   0x08048c3d <+686>:	call   0x804889c <_Unwind_Resume@plt>
   0x08048c42 <+691>:	mov    %ebx,%eax
   0x08048c44 <+693>:	add    $0x58,%esp
   0x08048c47 <+696>:	pop    %ebx
   0x08048c48 <+697>:	pop    %esi
   0x08048c49 <+698>:	mov    %ebp,%esp
   0x08048c4b <+700>:	pop    %ebp
   0x08048c4c <+701>:	ret    
End of assembler dump.

出现coredump可能是因为这一条指令

代码语言:javascript
复制
   0x08048bce <+575>:	call   *%esi

看一下esi的值:

代码语言:javascript
复制
(gdb) i r esi
esi            0x0	0

可见esi为0,确实是由于那一条指令引起的.

那么为什么esi的值是从哪里来的?

代码语言:javascript
复制
   0x08048b8f <+512>:	lea    0x48(%esp),%eax
   0x08048b93 <+516>:	mov    %eax,0x4(%esp)
   0x08048b97 <+520>:	lea    0x18(%esp),%eax
   0x08048b9b <+524>:	mov    %eax,(%esp)
   0x08048b9e <+527>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048ba3 <+532>:	mov    (%eax),%esi

可见esi是0x08048b9e处所调用的函数,

_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_的返回值

而_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_的实际名称:

代码语言:javascript
复制
[xuzhina@localhost s3_ex]$ c++filt _ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_
std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int (*)(int, int), std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int (*)(int, int)> > >::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

由于map的operater[]有一个参数,由上面看,可知map对象的地址是esp+0x18,那个参数是放在esp+0x48,而这个刚好是一个string对象的this指针.见0x08048b8a调用了构造函数

代码语言:javascript
复制
   0x08048b6f <+480>:	mov    0xc(%ebp),%eax
   0x08048b72 <+483>:	add    $0x8,%eax
   0x08048b75 <+486>:	mov    (%eax),%eax
   0x08048b77 <+488>:	lea    0x4f(%esp),%edx
   0x08048b7b <+492>:	mov    %edx,0x8(%esp)
   0x08048b7f <+496>:	mov    %eax,0x4(%esp)
   0x08048b83 <+500>:	lea    0x48(%esp),%eax
   0x08048b87 <+504>:	mov    %eax,(%esp)
   0x08048b8a <+507>:	call   0x80487ec <_ZNSsC1EPKcRKSaIcE@plt>

[xuzhina@localhost s3_ex]$ c++filt _ZNSsC1EPKcRKSaIcE
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)

可知,这个string的构造函数只是接收了一个参数,而这个参数是由ebp+c所指向内存地址偏移+8所得来的.

而ebp+0xc是main函数的第二个参数,由main函数的原型

int main( int argc, char* argv[] );

可知

这个参数应该是argv2,而argv2是字符串。它的值是多少呢?

代码语言:javascript
复制
(gdb) x /wx $ebp+0xc
0xbfd3def4:	0xbfd3df94
(gdb) x /8wx 0xbfd3df94
0xbfd3df94:	0xbfd3f543	0xbfd3f55c	0xbfd3f55e	0xbfd3f560
0xbfd3dfa4:	0x00000000	0xbfd3f562	0xbfd3f585	0xbfd3f5a4
(gdb) x /s 0xbfd3f55e
0xbfd3f55e:	 "/"

再看一下map的内容有哪些。由上面已经知道map对象的地址是esp+0x18。且由于上面参数的类型可以知道,这个map对象的key是string类型,而val是函数指针

代码语言:javascript
复制
(gdb) x /8wx $esp+0x18
0xbfd3de98:	0x00000001	0x00000000	0x089a7020	0x089a7090
0xbfd3dea8:	0x089a70c8	0x00000004	0x089a7014	0x0804bb84
(gdb) x /8wx 0x089a7020
0x89a7020:	0x00000001	0xbfd3de9c	0x089a7090	0x089a7058
0x89a7030:	0x089a7014	0x08048964	0x00000000	0x00000019
(gdb) x /8wx 0x089a7014
0x89a7014:	0x0000002b	0x00000000	0x00000021	0x00000001
0x89a7024:	0xbfd3de9c	0x089a7090	0x089a7058	0x089a7014
(gdb) x /s 0x089a7014
0x89a7014:	 "+"
(gdb) info symbol 0x08048964
add(int, int) in section .text of /home/xuzhina/code/s3_ex/xuzhina_dump_c07_s3_ex
(gdb) x /8wx 0x089a7090
0x89a7090:	0x00000001	0x089a7020	0x00000000	0x00000000
0x89a70a0:	0x089a7084	0x08048983	0x00000000	0x00000019
(gdb) x /8wx 0x089a7084
0x89a7084:	0x0000002a	0x00000000	0x00000021	0x00000001
0x89a7094:	0x089a7020	0x00000000	0x00000000	0x089a7084
(gdb) x /s 0x089a7084
0x89a7084:	 "*"
(gdb) info symbol 0x08048983
mul(int, int) in section .text of /home/xuzhina/code/s3_ex/xuzhina_dump_c07_s3_ex
(gdb) x /8wx 0x089a7058
0x89a7058:	0x00000001	0x089a7020	0x00000000	0x089a70c8
0x89a7068:	0x089a704c	0x08048972	0x00000000	0x00000019
(gdb) x /8wx 0x089a704c
0x89a704c:	0x0000002d	0x00000000	0x00000021	0x00000001
0x89a705c:	0x089a7020	0x00000000	0x089a70c8	0x089a704c
(gdb) x /s 0x089a704c
0x89a704c:	 "-"
(gdb) info symbol 0x08048972
sub(int, int) in section .text of /home/xuzhina/code/s3_ex/xuzhina_dump_c07_s3_ex
(gdb) x /8wx 0x089a70c8
0x89a70c8:	0x00000000	0x089a7058	0x00000000	0x00000000
0x89a70d8:	0x089a70bc	0x00000000	0x00000000	0x00020f21
(gdb) x /8wx 0x089a70bc
0x89a70bc:	0x0000002f	0x00000000	0x00000021	0x00000000
0x89a70cc:	0x089a7058	0x00000000	0x00000000	0x089a70bc
(gdb) x /s 0x089a70bc
0x89a70bc:	 "/"

而main函数调用_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_除了coredump的附近之外,还有三处调用了。

代码语言:javascript
复制
   0x080489ea <+91>:	lea    0x30(%esp),%eax
   0x080489ee <+95>:	mov    %eax,0x4(%esp)
   0x080489f2 <+99>:	lea    0x18(%esp),%eax
   0x080489f6 <+103>:	mov    %eax,(%esp)
   0x080489f9 <+106>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x080489fe <+111>:	movl   $0x8048964,(%eax)  

 0x08048a75 <+230>:	lea    0x38(%esp),%eax
   0x08048a79 <+234>:	mov    %eax,0x4(%esp)
   0x08048a7d <+238>:	lea    0x18(%esp),%eax
   0x08048a81 <+242>:	mov    %eax,(%esp)
---Type <return> to continue, or q <return> to quit---
   0x08048a84 <+245>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048a89 <+250>:	movl   $0x8048972,(%eax)

   0x08048b00 <+369>:	lea    0x40(%esp),%eax
   0x08048b04 <+373>:	mov    %eax,0x4(%esp)
   0x08048b08 <+377>:	lea    0x18(%esp),%eax
   0x08048b0c <+381>:	mov    %eax,(%esp)
   0x08048b0f <+384>:	call   0x8048cfc <_ZNSt3mapISsPFiiiESt4lessISsESaISt4pairIKSsS1_EEEixERS5_>
   0x08048b14 <+389>:	movl   $0x8048983,(%eax)

其中0x8048964,0x8048972,0x8048983正好是那三个函数指针。可见,main函数并没有往map对象里面放入”/”的val。

看一下程序代码,

代码语言:javascript
复制
  1 #include <map>
  2 #include <string>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 
  6 typedef int (*oper)(int a, int b );
  7 
  8 int add( int a, int b )
  9 {
 10     return a + b;
 11 }
 12 
 13 int sub( int a, int b )
 14 {
 15     return a - b;
 16 }
 17 
 18 int mul( int a, int b )
 19 {
 20     return a * b;
 21 }
 22 
 23 int main( int argc, char* argv[] )
 24 {
 25     if ( argc < 4 )
 26     {
 27         printf( "parameter less than 4\n" );
 28         return -1;
 29     }
 30 
 31     std::map< std::string, oper> operMap;
 32     operMap["+"] = &add;
 33     operMap["-"] = ⊂
 34     operMap["*"] = &mul;
 35 
 36     return operMap[argv[2]]( atoi( argv[1] ), atoi( argv[3] ) );
 37 }

可知,确实如上面所分析那样.所以,对于获取map里面的元素,用operator[]要慎重.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015年04月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档