栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

从信号处理程序中获取保存的指令指针地址

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从信号处理程序中获取保存的指令指针地址

/ sigsegv.c /
#if !defined(__cplusplus) && !defined(NO_CPP_DEMANGLE)#define NO_CPP_DEMANGLE#endif#include <memory.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <signal.h>#include <ucontext.h>#include <dlfcn.h>#ifndef NO_CPP_DEMANGLE#include <cxxabi.h>#ifdef __cplusplususing __cxxabiv1::__cxa_demangle;#endif#endif#ifdef HAS_ULSLIB#include "uls/logger.h"#define sigsegv_outp(x) sigsegv_outp(,gx)#else#define sigsegv_outp(x, ...) fprintf(stderr, x "n", ##__VA_ARGS__)#endif#if defined(REG_RIP)# define SIGSEGV_STACK_IA64# define REGFORMAT "%016lx"#elif defined(REG_EIP)# define SIGSEGV_STACK_X86# define REGFORMAT "%08x"#else# define SIGSEGV_STACK_GENERIC# define REGFORMAT "%x"#endifstatic void signal_segv(int signum, siginfo_t* info, void*ptr) { static const char *si_pres[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"}; int i, f = 0; ucontext_t *ucontext = (ucontext_t*)ptr; Dl_info dlinfo; void **bp = 0; void *ip = 0; sigsegv_outp("Segmentation Fault!"); sigsegv_outp("info.si_signo = %d", signum); sigsegv_outp("info.si_errno = %d", info->si_errno); sigsegv_outp("info.si_pre = %d (%s)", info->si_pre, si_pres[info->si_pre]); sigsegv_outp("info.si_addr = %p", info->si_addr); for(i = 0; i < NGREG; i++) sigsegv_outp("reg[%02d] = 0x" REGFORMAT, i, ucontext->uc_mcontext.gregs[i]);#ifndef SIGSEGV_NOSTACK#if defined(SIGSEGV_STACK_IA64) || defined(SIGSEGV_STACK_X86)#if defined(SIGSEGV_STACK_IA64) ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP]; bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];#elif defined(SIGSEGV_STACK_X86) ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP]; bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];#endif sigsegv_outp("Stack trace:"); while(bp && ip) { if(!dladdr(ip, &dlinfo)) break; const char *symname = dlinfo.dli_sname;#ifndef NO_CPP_DEMANGLE int status; char * tmp = __cxa_demangle(symname, NULL, 0, &status); if (status == 0 && tmp) symname = tmp;#endif sigsegv_outp("% 2d: %p <%s+%lu> (%s)", ++f, ip, symname, (unsigned long)ip - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname);#ifndef NO_CPP_DEMANGLE if (tmp) free(tmp);#endif if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main")) break; ip = bp[1]; bp = (void**)bp[0]; }#else sigsegv_outp("Stack trace (non-dedicated):"); sz = backtrace(bt, 20); strings = backtrace_symbols(bt, sz); for(i = 0; i < sz; ++i) sigsegv_outp("%s", strings[i]);#endif sigsegv_outp("End of stack trace.");#else sigsegv_outp("Not printing stack strace.");#endif _exit (-1);}static void __attribute__((constructor)) setup_sigsegv() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_sigaction = signal_segv; action.sa_flags = SA_SIGINFO; if(sigaction(SIGSEGV, &action, NULL) < 0) perror("sigaction");}$ g++ -fPIC -shared -o libsigsegv.so -ldl sigsegv$ export LD_PRELOAD=/path/to/libsigsegv.so

我在一个LUG上找到了此代码。无法进入页面将URL指向此处,因此粘贴了整个代码。发生SIGSEGV时,此代码将打印一条小的堆栈跟踪。不知道是否还有其他不使用ucontext_t的方式。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/408785.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号