现在的位置: 首页 > 综合 > 正文

Gcc也不是神,不可全信

2013年09月03日 ⁄ 综合 ⁄ 共 9051字 ⁄ 字号 评论关闭

这两天在调试一个奇怪的软件问题的时候,发现了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。

 

抱歉!评论已关闭.