这并没有回答这样做是否“好”的问题,但这是如何做到的。在我的应用程序中,我在自定义硬件、大页面、共享内存、NUMA 锁内存等之间进行了复杂的交互,并且可能会有看起来分配得当但当你触摸它时(在这种情况下写)的内存,它会在应用程序中间引发 BUS 错误或 SEGV 故障。我想想出一种测试内存地址的方法,以确保共享内存没有被节点锁定到没有足够内存的节点上,这样程序就会提前失败并显示优雅的错误消息。因此,这些信号处理程序仅用于这一段代码(5 个字节的小 memcpy),而不用于在应用程序使用时对其进行救援。我觉得这里很安全。
抱歉,如果这不是“正确的”。请发表评论,我会修复它。我根据提示和一些不起作用的示例代码将它拼凑在一起。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
sigjmp_buf JumpBuffer;
void handler(int);
int count = 0;
int main(void)
{
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&(sa.sa_mask));
sigaddset(&(sa.sa_mask), SIGSEGV);
sigaction(SIGSEGV, &sa, NULL);
while (1) {
int r = sigsetjmp(JumpBuffer,1);
if (r == 0) {
printf("Ready for memcpy, count=%d\n",count);
usleep(1000000);
char buffer[10];
#if 1
char* dst = buffer; // this won't do bad
#else
char* dst = nullptr; // this will cause a segfault
#endif
memcpy(dst,"12345",5); // trigger seg fault here
longjmp(JumpBuffer,2);
}
else if (r == 1)
{
printf("SEGV. count %d\n",count);
}
else if (r == 2)
{
printf("No segv. count %d\n",count);
}
}
return 0;
}
void handler(int sig)
{
count++;
siglongjmp(JumpBuffer, 1);
}
参考