首页 > 解决方案 > 使用 -fsanitize=address 编译的 c++ 代码崩溃

问题描述

我使用gcc 6.3.0地址清理器来编译以下代码:

#include <iostream>

int increment(int &x)
{
    x++;
    return x;
}

int main()
{
    int x = 0;
    increment(x);

    return 0;
}

代码被编译和检测。编译后代码的 Objdump (-S):

000008d0 <_Z9incrementRi>:

int increment(int &x) {
     8d0:   55                      push   %ebp
     8d1:   89 e5                   mov    %esp,%ebp
     8d3:   56                      push   %esi
     8d4:   53                      push   %ebx
     8d5:   83 ec 08                sub    $0x8,%esp
     8d8:   e8 9f 01 00 00          call   a7c <__x86.get_pc_thunk.cx>
     8dd:   81 c1 b3 89 00 00       add    $0x89b3,%ecx
    ++x;
     8e3:   8b 45 08                mov    0x8(%ebp),%eax
     8e6:   89 c2                   mov    %eax,%edx
     8e8:   c1 ea 03                shr    $0x3,%edx
     8eb:   81 c2 00 00 00 20       add    $0x20000000,%edx
     8f1:   0f b6 12                movzbl (%edx),%edx
     8f4:   84 d2                   test   %dl,%dl
     8f6:   0f 95 45 f7             setne  -0x9(%ebp)
     8fa:   89 c6                   mov    %eax,%esi
     8fc:   83 e6 07                and    $0x7,%esi
     8ff:   8d 5e 03                lea    0x3(%esi),%ebx
     902:   38 d3                   cmp    %dl,%bl
     904:   0f 9d c2                setge  %dl
     907:   22 55 f7                and    -0x9(%ebp),%dl
     90a:   84 d2                   test   %dl,%dl
     90c:   74 0b                   je     919 <_Z9incrementRi+0x49>
     90e:   83 ec 04                sub    $0x4,%esp
     911:   50                      push   %eax
     912:   89 cb                   mov    %ecx,%ebx
     914:   e8 a0 07 00 00          call   10b9 <__asan_report_load4>
     919:   8b 45 08                mov    0x8(%ebp),%eax
     91c:   8b 00                   mov    (%eax),%eax
     91e:   8d 50 01                lea    0x1(%eax),%edx
     921:   8b 45 08                mov    0x8(%ebp),%eax
     924:   89 10                   mov    %edx,(%eax)
}
     926:   90                      nop
     927:   8d 65 f8                lea    -0x8(%ebp),%esp
     92a:   5b                      pop    %ebx
     92b:   5e                      pop    %esi
     92c:   5d                      pop    %ebp
     92d:   c3                      ret    

0000092e <main>:

int main(void)
{
     92e:   8d 4c 24 04             lea    0x4(%esp),%ecx
     932:   83 e4 f8                and    $0xfffffff8,%esp
     935:   ff 71 fc                pushl  -0x4(%ecx)
     938:   55                      push   %ebp
     939:   89 e5                   mov    %esp,%ebp
     93b:   57                      push   %edi
     93c:   56                      push   %esi
     93d:   53                      push   %ebx
     93e:   51                      push   %ecx
     93f:   83 ec 60                sub    $0x60,%esp
     942:   e8 39 01 00 00          call   a80 <__x86.get_pc_thunk.bx>
     947:   81 c3 49 89 00 00       add    $0x8949,%ebx
     94d:   8d 75 90                lea    -0x70(%ebp),%esi
     950:   89 f7                   mov    %esi,%edi
     952:   8d 83 d0 05 00 00       lea    0x5d0(%ebx),%eax
     958:   83 38 00                cmpl   $0x0,(%eax)
     95b:   74 13                   je     970 <main+0x42>
     95d:   83 ec 04                sub    $0x4,%esp
     960:   6a 60                   push   $0x60
     962:   e8 b4 02 00 00          call   c1b <__asan_stack_malloc_1>
     967:   83 c4 08                add    $0x8,%esp
     96a:   85 c0                   test   %eax,%eax
     96c:   74 02                   je     970 <main+0x42>
     96e:   89 c6                   mov    %eax,%esi
     970:   8d 46 60                lea    0x60(%esi),%eax
     973:   c7 06 b3 8a b5 41       movl   $0x41b58ab3,(%esi)
     979:   8d 93 d0 e8 ff ff       lea    -0x1730(%ebx),%edx
     97f:   89 56 04                mov    %edx,0x4(%esi)
     982:   8d 93 9e 76 ff ff       lea    -0x8962(%ebx),%edx
     988:   89 56 08                mov    %edx,0x8(%esi)
     98b:   89 f3                   mov    %esi,%ebx
     98d:   c1 eb 03                shr    $0x3,%ebx
     990:   c7 83 00 00 00 20 f1    movl   $0xf1f1f1f1,0x20000000(%ebx)
     997:   f1 f1 f1 
     99a:   c7 83 04 00 00 20 04    movl   $0xf4f4f404,0x20000004(%ebx)
     9a1:   f4 f4 f4 
     9a4:   c7 83 08 00 00 20 f3    movl   $0xf3f3f3f3,0x20000008(%ebx)
     9ab:   f3 f3 f3 
    int x = 0;
     9ae:   c7 40 c0 00 00 00 00    movl   $0x0,-0x40(%eax)
    increment(x);
     9b5:   83 ec 04                sub    $0x4,%esp
     9b8:   83 e8 40                sub    $0x40,%eax
     9bb:   50                      push   %eax
     9bc:   e8 0f ff ff ff          call   8d0 <_Z9incrementRi>
     9c1:   83 c4 08                add    $0x8,%esp
    return 0;
     9c4:   b8 00 00 00 00          mov    $0x0,%eax
{
     9c9:   39 f7                   cmp    %esi,%edi
     9cb:   74 26                   je     9f3 <main+0xc5>
     9cd:   c7 06 0e 36 e0 45       movl   $0x45e0360e,(%esi)
     9d3:   c7 83 00 00 00 20 f5    movl   $0xf5f5f5f5,0x20000000(%ebx)
     9da:   f5 f5 f5 
     9dd:   c7 83 04 00 00 20 f5    movl   $0xf5f5f5f5,0x20000004(%ebx)
     9e4:   f5 f5 f5 
     9e7:   c7 83 08 00 00 20 f5    movl   $0xf5f5f5f5,0x20000008(%ebx)
     9ee:   f5 f5 f5 
     9f1:   eb 1e                   jmp    a11 <main+0xe3>
     9f3:   c7 83 00 00 00 20 00    movl   $0x0,0x20000000(%ebx)
     9fa:   00 00 00 
     9fd:   c7 83 04 00 00 20 00    movl   $0x0,0x20000004(%ebx)
     a04:   00 00 00 
     a07:   c7 83 08 00 00 20 00    movl   $0x0,0x20000008(%ebx)
     a0e:   00 00 00 
}
     a11:   8d 65 f0                lea    -0x10(%ebp),%esp
     a14:   59                      pop    %ecx
     a15:   5b                      pop    %ebx
     a16:   5e                      pop    %esi
     a17:   5f                      pop    %edi
     a18:   5d                      pop    %ebp
     a19:   8d 61 fc                lea    -0x4(%ecx),%esp
     a1c:   c3                      ret  

在以下行检测代码执行崩溃:

990:    c7 83 00 00 00 20 f1    movl   $0xf1f1f1f1,0x20000000(%ebx)

在调用 increment(int &x) 函数之前。ASAN 选项“stack-use-after-return”已启用。代码编译为:

gcc -O0 -g -fsanitize=address main.cpp

如果整数变量 x 被定义为全局变量,则代码不会被检测并且不会发生崩溃。
在我发布我的问题之前,我发现了这个问题,这与我的地址消毒剂问题非常相似。

所以我的问题是:
为什么代码的执行在上述行崩溃了?
仪器是否有可能在某个时候出错?

编辑
GCC 版本并配置标志

Configured with:   
../gcc-6.3.0/configure --prefix=/opt/V6.3.0 --target=i686-elf --with-pic 
--with-newlib --enable-fully-dynamic-string --enable-languages=c,c++ 
--disable-initfini-array --disable-nls --disable-shared --disable-multilib 
--disable-threads --disable-tls --disable-win32-registry --enable-sjlj-
exceptions --enable-frame-pointer --disable-__cxa_atexit --disable-libgomp 
--disable-libquadmath --disable-libssp --disable-libada --disable-libitm 
--disable-libstdcxx-verbose --disable-libstdcxx-visibility --with-default-
libstdcxx-abi=gcc4-compatible --without-headers 
    Thread model: single
    gcc version 6.3.0 (GCC)

标签: c++gccaddress-sanitizer

解决方案


推荐阅读