昨天,当我在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等其他平台,没有人能检测到溢出。谢谢你。
答案 0 :(得分:-1)
我没有使用过LabWindows / CVI,但是从你对它的简短讨论中,我猜测它在运行时检测到这个越界取消引用,而不是在编译时。静态代码分析(可在编译时执行而无需运行软件的正确性检查)受限于它们可以捕获的错误类型。在您的简单示例中,编译器可以想象地捕获此错误,但是在一般情况下它无法捕获这样的错误,因为跟踪可能进入大型程序的所有输入组合的数据流将是一个棘手的问题,即使对于最强大的超级计算机,即使只是为了解决这个问题而留下来。
在一般情况下可以捕获这类问题的唯一方法是通过动态程序分析:通过运行时边界检查自动检测代码本身,和/或通过跟踪所有内存边界的模拟器执行代码分配并验证针对这些边界的所有访问。前一种策略的一个示例实现是Ada编程语言,其中关键任务安全性被认为远比性能更重要。但就Ada而言,该语言旨在允许此类检查。 C或C ++语言的实现可能会做类似的事情,但是语言中原始指针的存在会使这更加困难,并且可能会使运行时成本更高。
在C和C ++中,如果您想要这种运行时边界检查(仅用于测试),您可以查看Valgrind。我知道没有其他工具可以更彻底地捕获越界访问。但要准备好让你的程序运行得非常慢。也许LabWindows / CVI类似于Valgrind?
在任何情况下,您都需要注意,无论您使用什么验证工具,使用运行时边界检查捕获错误代码的唯一方法是,如果您向程序提供输入,从而唤起出界限行为。任何验证工具都没有出现边界检查失败,这并不是确定您的程序没有此类错误的明确指标。