0

昨天,当我在C中运行一些简单的代码时,我发现CVI可以检测缓冲区溢出,这让我很困惑。

void main(void)
{
int a[10];
int buf[10];    
int test[10];
int *p = &buf[10];
*p = 1;
while(1);
}

当我可以运行这个程序时,发生了错误。消息是“越界指针的取消引用 1 个字节(1 个元素)超过数组末尾”(对不起,不允许发布图像)

我很困惑如何实现,因为我知道 C/C++ 没有内置的数组边界。我也在VC++6.0和Linux等其他平台上尝试过,没有人能检测到溢出。谢谢。

4

1 回答 1

-1

我没有使用过 LabWindows/CVI,但从你对它的简短讨论来看,我猜它在运行时检测到这种越界取消引用,而不是在编译时。静态代码分析(无需运行软件即可在编译时执行的正确性检查)受限于它们可以捕获的错误类型。在您的简单示例中,可以想象编译器可以捕获此错误,但在一般情况下它无法捕获此类错误,因为跟踪可能进入大型程序的所有输入组合的数据流即使对于最强大的程序也是一个棘手的问题超级计算机,即使被留下来咀嚼这个问题。

在一般情况下,唯一可以捕获此类问题的方法是通过动态程序分析:通过运行时边界检查自动检测代码本身,和/或通过跟踪所有内存分配边界并验证的模拟器执行代码对这些边界的所有访问。前一种策略的一个示例实现是 Ada 编程语言,其中关键任务安全被认为比性能更重要。但就 Ada 而言,该语言旨在允许此类检查。C 或 C++ 语言的实现可能会做类似的事情,但语言中原始指针的存在会使这变得更加困难,并且可能在运行时更加昂贵。

在 C 和 C++ 中,如果您想要这种运行时边界检查(仅用于测试),您可以查看 Valgrind。我知道没有其他工具可以更彻底地捕获越界访问。但是要为你的程序运行得很慢做好准备。也许 LabWindows/CVI 类似于 Valgrind?

在任何情况下,您都需要注意,无论您使用哪种验证工具,使用运行时边界检查来捕获错误代码的唯一方法是向程序提供引发越界行为的输入。任何验证工具都没有边界检查失败并不能明确表明您的程序没有此类错误。

于 2013-08-24T05:16:04.977 回答