3

在今天的讨论中,我发现VxWorksLynxOS中有检查,它告诉您为指针分配的地址来自有效范围。这是我第一次听到我分配的这个代码int *i=&variable;

我应该得到一个警告或错误,说明在我的应用程序中我无法将地址值分配给整数。

就像我进行 NULL 检查时一样,我只检查地址0x00000000。但是地址可能是这样的0x00000001。如果它是未映射的区域并且可能无法访问,这也是无效的情况。是否有人知道 Linux 有类似的事情,或者可以指导它在VxWorksLynxOS中是如何完成的。

有任何想法吗??

4

3 回答 3

6

您在 VxWorks 中寻找的函数称为vxMemProbe

基本上,vxMemProbe 库会插入特殊的异常处理代码来捕获页面错误或总线错误。vxMemProbe 函数用于检查地址是否对读或写有效。它还允许您测试特定地址是否可以通过给定的数据宽度(8、16、32、64 位)和对齐方式访问。

vxMemProbe 的底层机制与特定架构的异常处理机制相关联。vxMemProbe 库将代码插入到异常处理程序中。当您探测触发异常的地址时,处理程序会检查 vxMemProbe 是否触发了异常。如果是这样,则处理程序在异常之前恢复状态处理器并返回执行到调用 vxMemProbe 的位置,同时还通过给定调用约定的体系结构返回值。

于 2017-08-23T14:27:38.123 回答
3

这里有几个误解:

  • 从 C 语言的角度来看,只有一个指针值可以保证是无效的,这就是NULL. 对于其他值,这取决于上下文。当指针指向当前活动的对象时,它是有效的。(请注意,这在您的示例中是微不足道的,因为这仅在当前范围内可访问时才是int *i = &variable有效的语法)variable

  • NULL不一定意味着所有位为零的值。这是最常见的情况,但可能有平台使用不同的NULL指针位模式。C 标准甚至允许不同类型的指针对NULL. 尽管如此,转换0为指针类型可以保证生成NULL该类型的指针。

  • 我不知道您在 VxWorks 中到底指的是什么,但 Linux 当然会检查内存访问。如果进程试图访问未映射到虚拟地址空间中的地址,则会向该进程发送一个SIGSEGV信号,这会导致程序立即异常终止(Segmentation fault)。

于 2017-08-23T13:11:58.620 回答
3

一般来说,你不能做你想做的事,正如Felix Palmen 的回答中所解释的那样。

我应该得到一个警告或错误,说明在我的应用程序中我无法将地址值分配给整数。

静态且可靠地检测所有指针故障是不可能的(因为可以证明它等同于解决停机问题)。顺便说一句,您可能会考虑使用Frama-C等静态程序分析工具。

在 Linux 上,原则上,您可以在运行时测试给定地址在您的虚拟地址空间中是否有效,例如使用/proc/,例如通过解析/proc/self/maps伪文本文件(理解我的意思cat /proc/$$/maps,然后在终端中尝试cat /proc/self/maps)。请参阅proc(5)。在实践中我不建议经常这样做(它可能太慢),当然它不是编译器的内置函数(你应该自己编码)。顺便说一句,请注意ASLR

但是,有一些工具可以帮助检测(某些)错误地址使用,特别是valgrind地址清理工具,阅读有关GCC 的检测选项并尝试编译-fsanitize=address...

不要忘记使用所有警告和调试信息来编译您的代码,因此请使用gcc -Wall -Wextra -g它来编译它。

顺便说一句,如果您将某个局部变量的地址存储在某个全局指针中,并在该局部变量在范围内之后取消引用该指针,您仍然会有一些未定义的行为(即使您的代码没有崩溃,因为您通常会取消引用一些随机地址在你的调用堆栈上),你应该很害怕。应始终避免 UB。

于 2017-08-23T13:30:12.993 回答