在信号处理程序中获取文件、源代码行和变量名称
我为段错误安装了自定义信号处理程序,
void sa_sigHandler(int signo, siginfo_t *info, void *context) {
...
void *variableAddr = info->si_addr;
ucontext_t *uctx = (ucontext_t *)context;
unsigned long inst = uctx->uc_mcontext.gregs[REG_RIP];
// how to get file, source line and object name here ?
...
}
我看到了一些类似的问题,但没有找到具体的代码来实现这一点。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如 @zwol 评论的那样,这很难做到,最好使用现有的解决方案,例如 Breakpad 或 Apport。
如果必须在运行时报告此情况,最好将应用程序包装在 GDB 脚本中;类似于 gdb -ex run -ex where -ex quit /path/to/a.out 。
如果您仍然坚持在
C
或C++
中执行此操作,您可以从 libdwarf,但请注意,从信号处理程序中使用它会带来额外的复杂性(它不是异步信号安全的),因此您需要构建从程序计数器到源文件/行的映射信息提前,并且仅在崩溃时进行查找。导致
SIGSEGV
的地址可直接用作uctx->uc_mcontext .gregs[REG_RIP]
并且您的代码已经将其作为inst
获取,因此您不是在寻找它,而是在寻找其他东西。如果其他内容是“上述地址的文件/行信息”,请参见上文。您还可以
execv
此命令来打印该信息(这可以以异步安全的方式完成):/usr/bin/addr2line -fe /path/to/binary $inst.
As @zwol commented, this is pretty hard to do, and you'll be better off using existing solutions, such as Breakpad or Apport.
If you must report this at runtime, you may be better off wrapping the application in a GDB script; something like
gdb -ex run -ex where -ex quit /path/to/a.out
.If you still insist on doing this in
C
orC++
, you could benefit from libdwarf, but note that using it from a signal handler presents additional complications (it is not async-signal safe), so you'll need to build a map from program counters to source file/line info ahead of time, and only do the lookups at crash time.The address which caused
SIGSEGV
is directly available asuctx->uc_mcontext.gregs[REG_RIP]
and your code already gets that asinst
, so you are not looking for that, but for something else.If that something else is "file / line info for the above address", see above. You could also
execv
this command to print that info (this can be done in async-safe manner):/usr/bin/addr2line -fe /path/to/binary $inst
.