是否有类似于Unix中的IsBadReadPtr的函数?至少 IsBadReadPtr 的一些功能?我想编写一个程序,如果进程(如SIGSEGV
)发生不好的事情会做出反应并恢复一些信息。但我想检查指针以确保数据没有损坏,并查看它们是否可以安全访问。否则崩溃处理程序本身就会崩溃,从而变得无用。
有什么建议么?
是否有类似于Unix中的IsBadReadPtr的函数?至少 IsBadReadPtr 的一些功能?我想编写一个程序,如果进程(如SIGSEGV
)发生不好的事情会做出反应并恢复一些信息。但我想检查指针以确保数据没有损坏,并查看它们是否可以安全访问。否则崩溃处理程序本身就会崩溃,从而变得无用。
有什么建议么?
在 POSIX 系统上执行此操作的常用方法是使用write()
系统调用。如果无法读取内存,它将返回EFAULT
而不是发出信号:errno
int nullfd = open("/dev/random", O_WRONLY);
if (write(nullfd, pointer, size) < 0)
{
/* Not OK */
}
close(nullfd);
(/dev/random
在 Linux 上是一个很好的设备,因为它可以由任何用户编写,并且实际上会尝试读取给定的内存。在没有/dev/random
或不可写的操作系统上,尝试/dev/null
)。另一种选择是匿名管道,但如果您想测试一个大区域,您需要定期清除管道的读取端。
你怎么能这样做?
您尝试这样做,然后处理错误。
为此,首先设置一个 sigsetjmp 和一个 SIGSEGV 信号处理程序。然后尝试使用指针。如果它是一个错误的指针,则调用 SIGSEGV 处理程序,您可以跳转到安全位置并向用户报告错误。
在 Windows 或 Unix 上,您永远无法判断“是否可以安全地访问指针”。但对于某些 unix 平台上的一些类似信息,请查看cat /proc/self/maps
.
我在从虚拟机中运行 Ubuntu 时尝试从帧缓冲区读取“像素”时遇到了同样的问题。似乎没有安全的方法来检查访问而不崩溃或 acutally 挂起 gdb。StasM 提出的建议暗示我要遵循使用 fork 的“本地”解决方案。
void *some_address;
int pid = fork();
if (pid== 0)
{
someaddress[0] = some_address[0];
_exit(123);
}
bool access_ok = true;
int status;
int result = waitpid(pid, &status, 0);
if (result == -1 || WIFEXITED(status) == 0 || WEXITSTATUS(status) != 123)
{
access_ok = false;
}