【问题标题】:Detect integer overflow检测整数溢出
【发布时间】:2012-04-17 23:03:42
【问题描述】:

我正在使用一个大型 C 库,其中一些数组索引是使用 int 计算的。 我需要找到一种在运行时捕获整数溢出的方法,以便缩小到有问题的代码行。 Libc 手册状态:

FPE_INTOVF_TRAP 整数溢出(在 C 程序中不可能,除非您以特定于硬件的方式启用溢出捕获)。

但是 gcc 选项 -ffpe-trap 表明这些选项仅适用于 FP 号码?
那么如何启用整数溢出陷阱呢?我的系统是 Xeon/Core2, gcc-4.x, Linux 2.6

我查看了类似的问题,但它们都归结为修改代码。不过,我首先需要知道哪个代码有问题。
如果 Xeons 不能捕获溢出,哪些处理器可以?我也可以访问非 emt64 机器。

我同时找到了一个专为 llvm 设计的工具:http://embed.cs.utah.edu/ioc/ 但是似乎没有 gcc/icc 的等价物?

【问题讨论】:

  • 据我所知,没有 x86 处理器支持捕获整数溢出。许多 RISC cpu 都可以(至少 power 和 sparc 都可以),以及较旧的小型/大型机 CPU(例如 VAX)
  • 我可以试试 Power,没有 VAX。

标签: c debugging operating-system


【解决方案1】:

好的,我可能需要回答我自己的问题。

我发现 gcc 有 -ftrapv 选项,快速测试确实确认至少在我的系统溢出被困。随着我了解更多,我将发布更详细的信息,因为它似乎非常有用。

【讨论】:

    【解决方案2】:

    无符号整数运算当然不会溢出。

    使用有符号整数运算,溢出会导致未定义的行为;什么事情都可能发生。优化器正在积极优化溢出的内容。所以,你最好的选择是避免溢出,而不是在它发生时捕获它。考虑使用 CERT 'Secure Integer Library'(那里引用的 URL 似乎已经 AWOL/404;我不确定发生了什么)或 Google 的 'Safe Integer Operation' 库。

    如果您必须捕获溢出,则需要指定您感兴趣的平台(O/S 包括版本,编译器包括版本),因为答案将非常特定于平台。

    【讨论】:

    • 我需要知道要替换的 哪些 操作(使用 size_t)。我在问题中指定了系统/编译器。
    【解决方案3】:

    你知道溢出发生在哪一行吗?如果是这样,如果有问题的操作导致溢出,您也许可以查看汇编程序的进位标志。这是 CPU 用于进行大量计算的标志,虽然在 C 级别不可用,但可能会帮助您调试问题 - 或者至少让您有机会做某事。

    顺便说一句,找到了this gcc (-ftrapv) 的链接,该链接讨论了整数陷阱。可能是您正在寻找的。​​p>

    【讨论】:

    • 是否有机会在计数器上删除写入内存断点以帮助您解决问题?
    • 我不这么认为。有多个地方用int代替size_t,手动调试非常困难。不过我可能已经找到了解决方案。
    【解决方案4】:

    您可以在 gcc 中使用内联汇编程序来使用可能会产生溢出的指令,然后测试溢出标志以查看它是否确实发生了:

    int addo(int a, int b)
    {
        asm goto("add %0,%1; jo %l[overflow]" : : "r"(a), "r"(b) : "cc" : overflow);
        return a+b;
    overflow:
        return 0;
    }
    

    在这种情况下,它会尝试添加ab,如果添加,它会转到overflow 标签。如果没有溢出,它会继续,再次添加并返回它。

    这遇到了 GCC 限制,即内联 asm 块既不能输出值,也不能输出分支——如果不是这样,你就不需要第二次添加来实际获得结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      相关资源
      最近更新 更多