【发布时间】:2011-01-06 04:36:23
【问题描述】:
在 Unix 中是否有类似于 IsBadReadPtr 的函数?至少 IsBadReadPtr 的一些功能?
我想编写一个程序,如果某个进程(如SIGSEGV)发生不好的事情会做出反应并恢复一些信息。但我想检查指针以确保数据没有损坏,并查看它们是否可以安全访问。否则崩溃处理程序本身就会崩溃,从而变得无用。
有什么建议吗?
【问题讨论】:
在 Unix 中是否有类似于 IsBadReadPtr 的函数?至少 IsBadReadPtr 的一些功能?
我想编写一个程序,如果某个进程(如SIGSEGV)发生不好的事情会做出反应并恢复一些信息。但我想检查指针以确保数据没有损坏,并查看它们是否可以安全访问。否则崩溃处理程序本身就会崩溃,从而变得无用。
有什么建议吗?
【问题讨论】:
在 POSIX 系统上执行此操作的常用方法是使用 write() 系统调用。如果无法读取内存,它将在errno 中返回EFAULT,而不是发出信号:
int nullfd = open("/dev/random", O_WRONLY);
if (write(nullfd, pointer, size) < 0)
{
/* Not OK */
}
close(nullfd);
(/dev/random 在 Linux 上是一个很好的设备,因为它可以由任何用户编写,并且实际上会尝试读取给定的内存。在没有 /dev/random 或它不可写的操作系统上,试试/dev/null)。另一种选择是匿名管道,但如果您想测试一个大区域,您需要定期清除管道的读取端。
【讨论】:
/dev/random - 我已经更新了答案。
/dev/random 本身是否在 POSIX 中。共享内存对象方法也可能是一个好主意,但请注意,POSIX 将write()(和lseek())对共享内存对象的影响“未指定”。我怀疑最便携的解决方案是pipe() 文件描述符,但这需要定期读取或关闭/重新创建管道。
在 Windows 或 Unix 上,您永远无法判断“是否可以安全地访问指针”。但对于某些 unix 平台上的一些类似信息,请查看cat /proc/self/maps。
【讨论】:
"Cannot access memory at address blah-blah"。所以它知道我是否可以访问地址 blah-blah - 我想知道如何从我的程序中做同样的事情。
你是怎么做到的?
您尝试这样做,然后处理错误。
为此,首先设置一个 sigsetjmp 和一个 SIGSEGV 信号处理程序。然后尝试使用指针。如果它是一个错误的指针,则调用 SIGSEGV 处理程序,您可以跳转到安全位置并向用户报告错误。
【讨论】:
我在从虚拟机中运行 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;
}
【讨论】: