我想写一个信号处理程序来捕获SIGSEGV.我使用保护内存块进行读写
char *buffer;
char *p;
char a;
int pagesize = 4096;
mprotect(buffer,pagesize,PROT_NONE)
Run Code Online (Sandbox Code Playgroud)
这可以保护从缓冲区开始的内存大小字节的内存,防止任何读取或写入.
其次,我尝试读取内存:
p = buffer;
a = *p
Run Code Online (Sandbox Code Playgroud)
这将生成一个SIGSEGV,我的处理程序将被调用.到现在为止还挺好.我的问题是,一旦调用处理程序,我想通过这样做来改变内存的访问写入
mprotect(buffer,pagesize,PROT_READ);
Run Code Online (Sandbox Code Playgroud)
并继续正常运行我的代码.我不想退出该功能.在将来写入相同内存时,我想再次捕获信号并修改写入权限,然后记录该事件.
这是代码:
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
char *buffer;
int flag=0;
static void handler(int sig, siginfo_t *si, void *unused)
{
printf("Got SIGSEGV at address: 0x%lx\n",(long) si->si_addr);
printf("Implements the handler only\n");
flag=1;
//exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{ …
Run Code Online (Sandbox Code Playgroud) 我正在开发通过NDK与Android一起使用的本机应用程序.我需要在backtrace()
发生崩溃时调用该函数.问题是<execinfo.h>
NDK 没有 .
有没有其他方法来获得回溯?
我正在为Android(仅限ARM)编写这个,但我相信通用Linux的原理也是如此.
我正在尝试从信号处理程序中捕获堆栈跟踪,以便我可以在应用程序崩溃时记录它.这就是我想出来的用法<unwind.h>
.
初始化:
struct sigaction signalhandlerDescriptor;
memset(&signalhandlerDescriptor, 0, sizeof(signalhandlerDescriptor));
signalhandlerDescriptor.sa_flags = SA_SIGINFO;
signalhandlerDescriptor._u._sa_sigaction = signalHandler;
sigaction(SIGSEGV, &signalhandlerDescriptor, 0);
Run Code Online (Sandbox Code Playgroud)
代码本身:
struct BacktraceState
{
void** current;
void** end;
void* pc;
};
inline _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
{
BacktraceState* state = static_cast<BacktraceState*>(arg);
state->pc = (void*)_Unwind_GetIP(context);
if (state->pc)
{
if (state->current == state->end)
return _URC_END_OF_STACK;
else
*state->current++ = reinterpret_cast<void*>(state->pc);
}
return _URC_NO_REASON;
}
inline size_t captureBacktrace(void** addrs, size_t max, unsigned long pc)
{
BacktraceState state = {addrs, addrs + max, …
Run Code Online (Sandbox Code Playgroud) 我通过代码处理SIGSEGV:
int C()
{
int *i = NULL;
*i = 10; // Crash there
}
int B()
{
return C();
}
int A()
{
return B();
}
int main(void)
{
struct sigaction handler;
memset(&handler,0,sizeof(handler));
handler.sa_sigaction = handler_func;
handler.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV,&handler,NULL);
return(C());
}
Run Code Online (Sandbox Code Playgroud)
处理程序代码在哪里:
static int handler_func(int signal, siginfo_t info, void* rserved)
{
const void* stack[MAX_DEPTH];
StackCrowlState state;
state.addr = stack;
state.count = MAX_DEPTH;
_Unwind_Reason_Code code = _Unwind_Backtrace(trace_func,&state);
printf("Stack trace count: %d, code: %d\n",MAX_DEPTH - state.count, code);
kill(getpid(),SIGKILL);
}
static …
Run Code Online (Sandbox Code Playgroud) c ×3
android-ndk ×2
c++ ×2
linux ×2
android ×1
arm ×1
backtrace ×1
gcc ×1
mprotect ×1
signals ×1
stack-trace ×1
system-calls ×1