我试图在只读内存上捕获错误但无法捕获? 如果我处理了错误,那么它的程序可以继续,或者只有选项是退出/中止?
#include<iostream>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
char * F00()
{
char *s2="ab";
return s2;
}
void InvalidMem()
{
(F00())[0]='l';
}
void
termination_handler (int signum)
{
fprintf(stderr,"BUS error");
}
int
main(int argc, char **argv)
{
signal (SIGBUS, termination_handler);
InvalidMem();
for(int i = 0; i < 10; ++i)
std::cout<<" L " ;
return 0;
}
最佳答案
SIGBUS 意味着您正在访问一个未对齐的地址,SIGSEGV 意味着您正在访问一个您“不应该”访问的地址(无效地址,或者写入只读内存 - 在某些情况下内存可以是只写的,并且从这样的内存中读取也会导致 SIGSEGV )。
由于处理器并不真正知道当您最终进入信号处理程序时它处于什么状态,因此在这些情况下通常不可能仅从信号处理程序本身继续。相反,典型的方法是使用 setjmp
和 longjmp
来“恢复到已知点”。这可能是您代码的“主循环”,或某个错误恢复点。
所以,像这样:
jmp_buf reset;
int termination_handler(int signum)
{
longjmp(reset, 1);
}
int main()
{
if (setjmp(reset) != 0)
{
printf("We got back from signal handler")
...
}
signal (SIGBUS, termination_handler);
...
return 0;
}
应该注意的是,如果您在执行错误(如总线故障或地址故障)后实际上“继续”,您可能会遇到一些严重的麻烦 - 例如考虑:
// At global level:
some_lock lock;
// in some function.
....
lock->take();
some code that crashes;
lock->release();
所以,现在锁被持有,永远不会释放...下次您需要获取锁时代码可能会挂起...
关于c++ - 如何捕获 SIGBUS 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28124154/