这两天在调试一个奇怪的软件问题的时候,发现了GCC也会生成错误代码,所以,Gcc也不是神,不可全信
问题现象:
同一段代码,同一个程序, 在Fedora13里编译生成目标程序,可以正常运行。 在雨林木风3.0里编译生成的目标程序,运行就出“段错误”。
反复测试都是这个现象,最后将问题定位到一个函数的内部。使用gdb跟踪发现生成的代码有差异:
Fedora13 gcc 版本:
gcc (GCC) 4.4.4 20100503 (Red Hat 4.4.4-2)
gdb关键部分调试输出:
(gdb) x /16i $pc
=> 0x80496ab <zh_han7shU0sheg1mig1+493>: sub $0x8,%esp
0x80496ae <zh_han7shU0sheg1mig1+496>: lea -0x120(%ebp),%eax
0x80496b4 <zh_han7shU0sheg1mig1+502>: push %eax
0x80496b5 <zh_han7shU0sheg1mig1+503>: push $0x805be54
0x80496ba <zh_han7shU0sheg1mig1+508>:
call 0x804e7c9 <zh_Ge1sHi4shu5chu1>
0x80496bf <zh_han7shU0sheg1mig1+513>: add $0x10,%esp
0x80496c2 <zh_han7shU0sheg1mig1+516>: mov 0x80e5f70,%al
。。。 。。。
(gdb)
(gdb) x /16i $pc
=> 0x804e7c9 <zh_Ge1sHi4shu5chu1>: push %ebp
0x804e7ca <zh_Ge1sHi4shu5chu1+1>: mov %esp,%ebp
0x804e7cc <zh_Ge1sHi4shu5chu1+3>: sub $0x118,%esp
0x804e7d2 <zh_Ge1sHi4shu5chu1+9>: movl $0x0,-0xc(%ebp)
0x804e7d9 <zh_Ge1sHi4shu5chu1+16>: mov 0x8(%ebp),%eax
0x804e7dc <zh_Ge1sHi4shu5chu1+19>: test %eax,%eax
0x804e7de <zh_Ge1sHi4shu5chu1+21>:
jne 0x804e7ea <zh_Ge1sHi4shu5chu1+33>
0x804e7e0 <zh_Ge1sHi4shu5chu1+23>: mov $0x0,%eax
0x804e7e5 <zh_Ge1sHi4shu5chu1+28>:
jmp 0x804e887 <zh_Ge1sHi4shu5chu1+190>
0x804e7ea <zh_Ge1sHi4shu5chu1+33>: mov 0x8(%ebp),%eax
0x804e7ed <zh_Ge1sHi4shu5chu1+36>: sub $0xc,%esp
0x804e7f0 <zh_Ge1sHi4shu5chu1+39>: push %eax
0x804e7f1 <zh_Ge1sHi4shu5chu1+40>:
call 0x8052b86 <zh_Zi5Fu0chuan6chag5Du2>
0x804e7f6 <zh_Ge1sHi4shu5chu1+45>: add $0x10,%esp
0x804e7f9 <zh_Ge1sHi4shu5chu1+48>: mov %eax,-0x18(%ebp)
0x804e7fc <zh_Ge1sHi4shu5chu1+51>: mov -0x18(%ebp),%eax
(gdb)
0x804e7ff <zh_Ge1sHi4shu5chu1+54>: lea 0x1(%eax),%edx
0x804e802 <zh_Ge1sHi4shu5chu1+57>: sub $0x8,%esp
0x804e805 <zh_Ge1sHi4shu5chu1+60>: push $0x3b6
0x804e80a <zh_Ge1sHi4shu5chu1+65>: push $0x805cd71
0x804e80f <zh_Ge1sHi4shu5chu1+70>: lea -0x18(%ebp),%eax
0x804e812 <zh_Ge1sHi4shu5chu1+73>: push %eax
0x804e813 <zh_Ge1sHi4shu5chu1+74>: push %edx
0x804e814 <zh_Ge1sHi4shu5chu1+75>: push $0x100
0x804e819 <zh_Ge1sHi4shu5chu1+80>: lea -0x118(%ebp),%eax
0x804e81f <zh_Ge1sHi4shu5chu1+86>: push %eax
0x804e820 <zh_Ge1sHi4shu5chu1+87>:
call 0x804ff18 <zh_nei3cun1_tiao2jiAn1fen4pei6>
0x804e825 <zh_Ge1sHi4shu5chu1+92>: add $0x20,%esp
0x804e828 <zh_Ge1sHi4shu5chu1+95>: mov %eax,-0xc(%ebp)
0x804e82b <zh_Ge1sHi4shu5chu1+98>: mov -0x18(%ebp),%eax
0x804e82e <zh_Ge1sHi4shu5chu1+101>: mov %eax,%edx
0x804e830 <zh_Ge1sHi4shu5chu1+103>: mov 0x8(%ebp),%eax
(gdb)
0x804e833 <zh_Ge1sHi4shu5chu1+106>: sub $0x4,%esp
0x804e836 <zh_Ge1sHi4shu5chu1+109>: push %edx
0x804e837 <zh_Ge1sHi4shu5chu1+110>: pushl -0xc(%ebp)
0x804e83a <zh_Ge1sHi4shu5chu1+113>: push %eax
0x804e83b <zh_Ge1sHi4shu5chu1+114>:
call 0x804dff9 <zh_guo2biao0Ge1sHi4zhuan3C_Ge1sHi4>
0x804e840 <zh_Ge1sHi4shu5chu1+119>: add $0x10,%esp
0x804e843 <zh_Ge1sHi4shu5chu1+122>: lea 0x8(%ebp),%eax
0x804e846 <zh_Ge1sHi4shu5chu1+125>: add $0x4,%eax
0x804e849 <zh_Ge1sHi4shu5chu1+128>: mov %eax,-0x10(%ebp)
0x804e84c <zh_Ge1sHi4shu5chu1+131>: mov -0xc(%ebp),%eax
0x804e84f <zh_Ge1sHi4shu5chu1+134>: sub $0x8,%esp
0x804e852 <zh_Ge1sHi4shu5chu1+137>: pushl -0x10(%ebp)
0x804e855 <zh_Ge1sHi4shu5chu1+140>: push %eax
0x804e856 <zh_Ge1sHi4shu5chu1+141>: call 0x8048e00 <vprintf@plt>
0x804e85b <zh_Ge1sHi4shu5chu1+146>: add $0x10,%esp
0x804e85e <zh_Ge1sHi4shu5chu1+149>: mov %eax,-0x14(%ebp)
(gdb)
0x804e861 <zh_Ge1sHi4shu5chu1+152>: movl $0x0,-0x10(%ebp)
0x804e868 <zh_Ge1sHi4shu5chu1+159>: push $0x3bd
0x804e86d <zh_Ge1sHi4shu5chu1+164>: push $0x805cd71
0x804e872 <zh_Ge1sHi4shu5chu1+169>: pushl -0xc(%ebp)
0x804e875 <zh_Ge1sHi4shu5chu1+172>: lea -0x118(%ebp),%eax
0x804e87b <zh_Ge1sHi4shu5chu1+178>: push %eax
0x804e87c <zh_Ge1sHi4shu5chu1+179>:
call 0x804ffba <zh_nei3cun1_tiao2jiAn1ShI0Fag0>
0x804e881 <zh_Ge1sHi4shu5chu1+184>: add $0x10,%esp
0x804e884 <zh_Ge1sHi4shu5chu1+187>: mov -0x14(%ebp),%eax
0x804e887 <zh_Ge1sHi4shu5chu1+190>: leave
0x804e888 <zh_Ge1sHi4shu5chu1+191>: ret
0x804e889 <zh_xI8Ge1sHi4shu5chu1>: push %ebp
0x804e88a <zh_xI8Ge1sHi4shu5chu1+1>: mov %esp,%ebp
0x804e88c <zh_xI8Ge1sHi4shu5chu1+3>: sub $0x18,%esp
0x804e88f <zh_xI8Ge1sHi4shu5chu1+6>: mov 0x8(%ebp),%eax
0x804e892 <zh_xI8Ge1sHi4shu5chu1+9>: test %eax,%eax
(gdb)
雨林木风3.0 Gcc版本:
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
gdb关键部分调试输出:
(gdb) x /16i $pc
=> 0x804970b <zh_han7shU0sheg1mig1+493>: sub $0x8,%esp
0x804970e <zh_han7shU0sheg1mig1+496>: lea -0x120(%ebp),%eax
0x8049714 <zh_han7shU0sheg1mig1+502>: push %eax
0x8049715 <zh_han7shU0sheg1mig1+503>: push $0x805c8f4
0x804971a <zh_han7shU0sheg1mig1+508>:
call 0x804eb9f <zh_Ge1sHi4shu5chu1>
0x804971f <zh_han7shU0sheg1mig1+513>: add $0x10,%esp
0x8049722 <zh_han7shU0sheg1mig1+516>: mov 0x80e6f70,%al
0x8049727 <zh_han7shU0sheg1mig1+521>: test %al,%al
0x8049729 <zh_han7shU0sheg1mig1+523>:
jne 0x80497a8 <zh_han7shU0sheg1mig1+650>
0x804972b <zh_han7shU0sheg1mig1+525>: sub $0xc,%esp
0x804972e <zh_han7shU0sheg1mig1+528>: push $0x805c97c
0x8049733 <zh_han7shU0sheg1mig1+533>:
call 0x804dc14 <zh_shu5chu1Zi5Fu0chuan6big8huan5Xig0>
0x8049738 <zh_han7shU0sheg1mig1+538>: add $0x10,%esp
0x804973b <zh_han7shU0sheg1mig1+541>: sub $0xc,%esp
0x804973e <zh_han7shU0sheg1mig1+544>: push $0x805ca04
0x8049743 <zh_han7shU0sheg1mig1+549>:
call 0x804dc14 <zh_shu5chu1Zi5Fu0chuan6big8huan5Xig0>
(gdb)
(gdb) x /16i $pc
=> 0x804eb9f <zh_Ge1sHi4shu5chu1>: push %ebp
0x804eba0 <zh_Ge1sHi4shu5chu1+1>: mov %esp,%ebp
0x804eba2 <zh_Ge1sHi4shu5chu1+3>: sub $0x138,%esp
0x804eba8 <zh_Ge1sHi4shu5chu1+9>: mov 0x8(%ebp),%eax
0x804ebab <zh_Ge1sHi4shu5chu1+12>: mov %eax,-0x12c(%ebp)
0x804ebb1 <zh_Ge1sHi4shu5chu1+18>: mov %gs:0x14,%eax
0x804ebb7 <zh_Ge1sHi4shu5chu1+24>: mov %eax,-0xc(%ebp)
0x804ebba <zh_Ge1sHi4shu5chu1+27>: xor %eax,%eax
0x804ebbc <zh_Ge1sHi4shu5chu1+29>: movl $0x0,-0x11c(%ebp)
0x804ebc6 <zh_Ge1sHi4shu5chu1+39>: mov -0x12c(%ebp),%eax
0x804ebcc <zh_Ge1sHi4shu5chu1+45>: test %eax,%eax
0x804ebce <zh_Ge1sHi4shu5chu1+47>:
jne 0x804ebda <zh_Ge1sHi4shu5chu1+59>
0x804ebd0 <zh_Ge1sHi4shu5chu1+49>: mov $0x0,%eax
0x804ebd5 <zh_Ge1sHi4shu5chu1+54>:
jmp 0x804eca7 <zh_Ge1sHi4shu5chu1+264>
0x804ebda <zh_Ge1sHi4shu5chu1+59>: mov -0x12c(%ebp),%eax
0x804ebe0 <zh_Ge1sHi4shu5chu1+65>: sub $0xc,%esp
(gdb)
0x804ebe3 <zh_Ge1sHi4shu5chu1+68>: push %eax
0x804ebe4 <zh_Ge1sHi4shu5chu1+69>:
call 0x805351e <zh_Zi5Fu0chuan6chag5Du2>
0x804ebe9 <zh_Ge1sHi4shu5chu1+74>: add $0x10,%esp
0x804ebec <zh_Ge1sHi4shu5chu1+77>: mov %eax,-0x114(%ebp)
0x804ebf2 <zh_Ge1sHi4shu5chu1+83>: mov -0x114(%ebp),%eax
0x804ebf8 <zh_Ge1sHi4shu5chu1+89>: lea 0x1(%eax),%edx
0x804ebfb <zh_Ge1sHi4shu5chu1+92>: sub $0x8,%esp
0x804ebfe <zh_Ge1sHi4shu5chu1+95>: push $0x3b6
0x804ec03 <zh_Ge1sHi4shu5chu1+100>: push $0x805d811
0x804ec08 <zh_Ge1sHi4shu5chu1+105>: lea -0x114(%ebp),%eax
0x804ec0e <zh_Ge1sHi4shu5chu1+111>: push %eax
0x804ec0f <zh_Ge1sHi4shu5chu1+112>: push %edx
0x804ec10 <zh_Ge1sHi4shu5chu1+113>: push $0x100
0x804ec15 <zh_Ge1sHi4shu5chu1+118>: lea -0x10c(%ebp),%eax
0x804ec1b <zh_Ge1sHi4shu5chu1+124>: push %eax
0x804ec1c <zh_Ge1sHi4shu5chu1+125>:
call 0x8050869 <zh_nei3cun1_tiao2jiAn1fen4pei6>
(gdb)
0x804ec21 <zh_Ge1sHi4shu5chu1+130>: add $0x20,%esp
0x804ec24 <zh_Ge1sHi4shu5chu1+133>: mov %eax,-0x11c(%ebp)
0x804ec2a <zh_Ge1sHi4shu5chu1+139>: mov -0x114(%ebp),%eax
0x804ec30 <zh_Ge1sHi4shu5chu1+145>: mov %eax,%edx
0x804ec32 <zh_Ge1sHi4shu5chu1+147>: mov -0x12c(%ebp),%eax
0x804ec38 <zh_Ge1sHi4shu5chu1+153>: sub $0x4,%esp
0x804ec3b <zh_Ge1sHi4shu5chu1+156>: push %edx
0x804ec3c <zh_Ge1sHi4shu5chu1+157>: pushl -0x11c(%ebp)
0x804ec42 <zh_Ge1sHi4shu5chu1+163>: push %eax
0x804ec43 <zh_Ge1sHi4shu5chu1+164>:
call 0x804e0e0 <zh_guo2biao0Ge1sHi4zhuan3C_Ge1sHi4>
0x804ec48 <zh_Ge1sHi4shu5chu1+169>: add $0x10,%esp
0x804ec4b <zh_Ge1sHi4shu5chu1+172>: lea -0x12c(%ebp),%eax
0x804ec51 <zh_Ge1sHi4shu5chu1+178>: add $0x4,%eax
0x804ec54 <zh_Ge1sHi4shu5chu1+181>: mov %eax,-0x118(%ebp)
0x804ec5a <zh_Ge1sHi4shu5chu1+187>: mov -0x11c(%ebp),%eax
0x804ec60 <zh_Ge1sHi4shu5chu1+193>: sub $0x8,%esp
(gdb)
0x804ec63 <zh_Ge1sHi4shu5chu1+196>: pushl -0x118(%ebp)
0x804ec69 <zh_Ge1sHi4shu5chu1+202>: push %eax
0x804ec6a <zh_Ge1sHi4shu5chu1+203>: call 0x8048e48 <vprintf@plt>
0x804ec6f <zh_Ge1sHi4shu5chu1+208>: add $0x10,%esp
0x804ec72 <zh_Ge1sHi4shu5chu1+211>: mov %eax,-0x110(%ebp)
0x804ec78 <zh_Ge1sHi4shu5chu1+217>: movl $0x0,-0x118(%ebp)
0x804ec82 <zh_Ge1sHi4shu5chu1+227>: push $0x3bd
0x804ec87 <zh_Ge1sHi4shu5chu1+232>: push $0x805d811
0x804ec8c <zh_Ge1sHi4shu5chu1+237>: pushl -0x11c(%ebp)
0x804ec92 <zh_Ge1sHi4shu5chu1+243>: lea -0x10c(%ebp),%eax
0x804ec98 <zh_Ge1sHi4shu5chu1+249>: push %eax
0x804ec99 <zh_Ge1sHi4shu5chu1+250>:
call 0x805090b <zh_nei3cun1_tiao2jiAn1ShI0Fag0>
0x804ec9e <zh_Ge1sHi4shu5chu1+255>: add $0x10,%esp
0x804eca1 <zh_Ge1sHi4shu5chu1+258>: mov -0x110(%ebp),%eax
0x804eca7 <zh_Ge1sHi4shu5chu1+264>: mov -0xc(%ebp),%edx
0x804ecaa <zh_Ge1sHi4shu5chu1+267>: xor %gs:0x14,%edx
(gdb)
上面蓝色是正确的, 红色是错误的。
大家以后在使用中,要注意规避这个版本的GCC。