崩溃后程序保持运行状态而不退出
来源:互联网 发布:linux运维会被云取代吗 编辑:程序博客网 时间:2024/05/04 05:45
参考:
http://blog.csdn.net/langresser_king/article/details/8288195
http://stackoverflow.com/questions/2663456/how-to-write-a-signal-handler-to-catch-sigsegv
When your signal handler returns (assuming it doesn't call exit or longjmp or something that prevents it from actually returning), the code will continue at the point the signal occurred, reexecuting the same instruction. Since at this point, the memory protection has not been changed, it will just throw the signal again, and you'll be back in your signal handler in an infinite loop.
So to make it work, you have to call mprotect in the signal handler. Unfortunately, as Steven Schansker notes, mprotect is not async-safe, so you can't safely call it from the signal handler. So, as far as POSIX is concerned, you're screwed.
Fortunately on most implementations (all modern UNIX and Linux variants as far as I know), mprotect is a system call, so is safe to call from within a signal handler, so you can do most of what you want. The problem is that if you want to change the protections back after the read, you'll have to do that in the main program after the read.
Another possibility is to do something with the third argument to the signal handler, which points at an OS and arch specific structure that contains info about where the signal occurred. On Linux, this is a ucontext structure, which contains machine-specific info about the $PC address and other register contents where the signal occurred. If you modify this, you change where the signal handler will return to, so you can change the $PC to be just after the faulting instruction so it won't re-execute after the handler returns. This is very tricky to get right (and non-portable too).
The ucontext structure is defined in <ucontext.h>. Within the ucontext the field uc_mcontext contains the machine context, and within that, the array gregs contains the general register context. So in your signal handler:
ucontext *u = (ucontext *)unused;
unsigned char *pc = (unsigned char *)u->uc_mcontext.gregs[REG_RIP];
will give you the pc where the exception occurred. You can read it to figure out what instruction it was that faulted, and do something different.
As far as the portability of calling mprotect in the signal handler is concerned, any system that follows either the SVID spec or the BSD4 spec should be safe -- they allow calling any system call (anything in section 2 of the manual) in a signal handler.
参考《unix高级环境编程》
while(1){ registerExceptionCatcher(); if(sigsetjmp(jmpbuf, 1)) { __DEBUG_LOG("jump back here #594"); registerExceptionCatcher(); continue; } canjump = 1; // 可能崩溃的代码 unregisterExceptionCatcher(); }static void sighandler (int);static sigjmp_buf jmpbuf;static volatile sig_atomic_t canjump;static void sighandler(int signum){ if (0 == canjump) { __DEBUG_LOG("canjump 0"); return; } struct tm *t = NULL; time_t stm; time(&stm); t = localtime(&stm); char timeBuf[64] = {0}; if(t != NULL) { snprintf(timeBuf,50,"%s %d-%02d-%02d %02d:%02d",t->tm_zone,t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min); } __DEBUG_LOG("[crash] sighandler signum:%d, %s", signum, timeBuf); canjump = 0; siglongjmp(jmpbuf, 1); /* jump back to the line before crash */}static struct sigaction act, oact;void registerExceptionCatcher(){ memset(&act, 0, sizeof(sigaction)); act._u._sa_handler = sighandler; act.sa_flags = SA_RESETHAND; sigemptyset(&act.sa_mask); sigaction(SIGSEGV, &act, &oact);}
0 0
- 崩溃后程序保持运行状态而不退出
- Linux 命令,如何让运行一个jar程序,当控制台退出后,仍然保持运行状态
- wpf 程序异常捕获,而不崩溃退出
- SSH Telnet 终端退出后保持程序继续运行
- SSH Telnet 终端退出后保持程序继续运行
- SSH Telnet 终端退出后保持程序继续运行 收藏
- 通过tmux让程序在ssh退出后保持运行
- Android:退出程序后保持Serivce开启不关闭
- 用nohup来保障后台运行的程序不因终端shell退出而终止
- Android 当打开“开发者模式”中的“不保留活动”后,程序应当怎么保持正常运行
- 保持进程在Shell退出后能继续运行方法
- 保持进程在Shell退出后能继续运行方法
- linux帐号退出后,仍保持运行, nohup
- Activity运行状态以及完全退出程序
- java打包jar后,使之一直在linux上运行,不随终端退出而关闭
- DigitalClock---TextClock---AnalogClock---Chronometer---程序退出保持后台运行设置
- 开机后直接运行您的程序而不显示Windows CE桌面
- 开机后直接运行您的程序而不显示Windows CE桌面
- 单片机项目:驱动VS1003模块
- Oracle数据库程序包全局变量的应用
- Android studio设置requestWindowFeature(Window.FEATURE_NO_TITLE);出错
- 简单理解设计模式之工厂模式
- 使用List的时候会将对象全部取出
- 崩溃后程序保持运行状态而不退出
- sctf 2014 pwn300
- 异或算法在算法求解中的妙用
- Linux 下编译Android-VLC开源播放器详解(附源码下载)
- 数据链路层常见威胁与防御技术
- 第三周 项目 3 求合集并集(补)
- js 放大镜
- win 32Api获取系统内存函数
- 搭建Vagrant的Debian8的base box