【问题标题】:clang sanitizers incorrectly catching integer overflowclang sanitizers 错误地捕获整数溢出
【发布时间】:2020-01-16 10:24:22
【问题描述】:

假设我的size_typeuint64_t,我有以下循环(其中sz 也是size_type

for ( size_type i= 0; i < sz; ++i ) {
     //something
     if ( i+1 == sz ) { //<-- here
         ///
     }
}

现在,当使用标志-fno-omit-frame-pointer -fsanitize=undefined -O2 -fsanitize=address 编译它时,我收到一个运行时错误,指出在上面的代码 sn-p 中标记here 的地方,2147483647 + 1 cannot fit into integersz 确实是比2^31-1 大一点的东西。但是,一切都应该没问题,因为uint64_t 可以保存该值,并且根据转换规则,i+1 应该提升为uint64_t。我错过了什么? 编辑:不是uint64_t 总是有64 位吗?那么,2147...-value 只是32 位,我们应该还是可以的。我现在在没有消毒剂的情况下运行我的东西,到目前为止还没有发生崩溃。 编辑:

clang 版本 8.0.0-3~ubuntu18.04.1 (tags/RELEASE_800/final) 目标: x86_64-pc-linux-gnu 线程模型:posix

而且我还有如下链接器标志

set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address")

也许这也有干扰?一世 知道编译器资源管理器无法重现该错误,这很奇怪,需要我进一步调查。

【问题讨论】:

  • 我无法重现它。
  • 你用的是哪个版本的clang?
  • 我假设您在没有 -fsanitize=address 的情况下得到相同的问题,在这种情况下我无法重现:godbolt.org/z/4hygZE(另请注意,两个或更多人只需要打开您的代码sn-p 变成可以实际编译和运行的东西。如果您自己提供它,它将为每个人节省大量时间 - 更是如此,因为我们不会被困在查看实际上不会重现问题的代码。)
  • 检查这个if ( i == sz - 1 ) 有什么好处?只要sz &gt; 0 应该没问题,i 不会溢出

标签: c++ clang sanitizer


【解决方案1】:

在最后一次迭代中,i = UINT64_MAX - 1i+1 = UINT64_MAXi &lt;= UINT64_MAX 在所有情况下都是如此。

for ( size_type i= 0; i < sz; ++i ) {
     //something
     if ( i+1 == sz ) { //<-- here
         ///
     }
}

没有溢出。 clang 中可能存在错误,它试图进行不正确的归纳变量优化。

clang-8, rcx 递增直到达到 0。这可能导致 off by 1 错误。

.LBB1_4:
        neg     rcx 
.LBB1_5:                                # =>This Inner Loop Header: Depth=1
        cmp     rax, rdi 
        jne     .LBB1_7
        mov     qword ptr [rsp - 8], rdi 
.LBB1_7:                                #   in Loop: Header=BB1_5 Depth=1
        add     rdi, 1
        inc     rcx 
        jne     .LBB1_5
.LBB1_8:

当clang-9。 rcx 递减,直到达到 0。

.LBB1_7:
        ret 
.LBB1_6:                                #   in Loop: Header=BB1_4 Depth=1
        add     rdi, 1
        add     rcx, -1
        je      .LBB1_7
.LBB1_4:                                # =>This Inner Loop Header: Depth=1
        cmp     rax, rdi 
        jne     .LBB1_6
        mov     qword ptr [rsp - 8], rdi 
        jmp     .LBB1_6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2012-03-14
    相关资源
    最近更新 更多