简体   繁体   English

如何捕捉SIGBUS错误?

[英]How to catch SIGBUS error?

I am trying to catch the error on read only memory but unable to do it? 我正在尝试在只读存储器上捕获错误,但无法执行此操作? If i handle the error then it program can continue or only option is exit/abort? 如果我处理了错误,则程序可以继续执行,或者只有退出/中止选项?

 #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 means you are accessing an unaligned address, SIGSEGV means you are accessing an address you are "not supposed to" (either invalid address, or writing to read-only memory - in some cases memory can be write-only, and a read from such memory would then result in SIGSEGV too). SIGBUS表示您正在访问未对齐的地址,SIGSEGV表示您正在访问“不应该”的地址(无效地址,或写入只读存储器-在某些情况下,存储器可以是只读的,而从中读取这样的记忆也会导致SIGSEGV)。

Since the processor doesn't really know how what state it is in when you end up in the signal handler, it is typically not possible to just continue from the signal handler itself in these cases. 由于当您最终进入信号处理程序时,处理器并不真正知道它处于什么状态,因此在这些情况下,通常无法仅从信号处理程序本身继续。 Instead, the typical approach is to use setjmp and longjmp to "recover to a known point". 相反,典型的方法是使用setjmplongjmp来“恢复到已知点”。 This may be the "main loop" of your code, or some error recovery point. 这可能是代码的“主循环”或某个错误恢复点。

So, something like this: 因此,如下所示:

 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;
 }

It should be noted that you can get into some serious trouble if you actually "keep going" after execution errors like bus fault or address fault - consider for example: 应该注意的是,如果您在总线错误或地址错误等执行错误之后实际上“继续前进”,则会遇到一些严重的麻烦-例如:

// At global level:
  some_lock lock;

// in some function. 
  ....
  lock->take();
  some code that crashes;
  lock->release();

So, now the lock is held, and never released... Code will probably hang next time you need to take the lock... 因此,现在该锁已被持有,并且从未释放过...下次您需要使用该锁时,代码可能会挂起...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM