未检测到越界指针算术?

Posted

技术标签:

【中文标题】未检测到越界指针算术?【英文标题】:Out of bounds pointer arithmetic not detected? 【发布时间】:2019-04-25 18:02:44 【问题描述】:

根据Wikipedia 和this,这段代码是未定义的行为:

#include <iostream>
int main(int, char**) 
    int data[1] = 123;
    int* p = data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;

使用clang++-6.0 -fsanitize=undefined 编译并执行,检测到未定义的行为,这太棒了,我收到以下消息:

ub.cpp:5:19: runtime error: index 5 out of bounds for type 'int [1]'

但是当我不使用数组时,无法检测到未定义的行为:

#include <iostream>
int main(int, char**) 
    int data = 123;
    int* p = &data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;

消毒剂没有检测到任何东西,即使这是仍然未定义的行为。 Valgrind 也没有显示任何问题。有什么方法可以检测到这种未定义的行为?

由于我从不访问任何无效数据,因此这不是 Recommended way to track down array out-of-bound access/write in C program 的重复。

【问题讨论】:

评论不用于扩展讨论;这个对话是moved to chat。 【参考方案1】:

该标准非常明确地规定,大多数形式的未定义行为是“不需要诊断”。这意味着您的编译器没有义务诊断 UB(这也是不合理的,因为在许多情况下很难做到这一点)。相反,允许编译器假设你“当然没有”编写任何 UB 并生成代码,就好像你没有那样。如果你做了,那一切都由你自己负责,你可以保留碎片。

一些工具(如asanubsan 并将您的编译器警告级别设置为11)会为您检测一些 UB。但不是全部。

您的编译器实现者不会伤害您。他们确实会在可能的情况下尝试警告您注意 UB。因此,至少您应该启用所有警告并让它们尽可能地帮助您。

检测 UB 的一种方法是深入了解 C++ 标准并非常仔细地阅读代码。但是,你真的不能做得比这更好 + 让一些工具帮助你找到唾手可得的果实。你只是必须知道(所有)规则并且知道你在做什么。

C++ 中没有辅助轮或类似的东西。

【讨论】:

以上是关于未检测到越界指针算术?的主要内容,如果未能解决你的问题,请参考以下文章

Asan快速定位内存越界内存泄漏

在android中,数据下标越界,则发生啥异常

【日更挑战】解决Kafka的Offset越界问题(未完)

调试教程

调试教程

越界异常和空指针异常