在 i386 上实现回溯
我目前正在将我们的代码从 alpha (Tru64) 移植到 C 语言的 i386 处理器 (Linux)。 一切都进行得很顺利,直到我考虑移植我们的 异常处理例程。目前我们有一个父进程 产生大量子进程,并且当这些子进程之一 fatal's (unfielded) 我有例程来捕获该过程。
我目前正在努力寻找实现回溯例程的最佳方法,该例程可以在错误日志中列出函数地址,目前我的例程仅打印导致异常的信号和异常限定符代码。
任何帮助都会得到极大的帮助,理想情况下我会为所有处理器编写错误处理,但是在这个阶段我只关心 i386 和 x86_64。
谢谢马克
I am currently porting our code from an alpha (Tru64) to an i386 processor (Linux) in C.
Everything has gone pretty smoothly up until I looked into porting our
exception handling routine. Currently we have a parent process which
spawns lots of sub processes, and when one of these sub-processes
fatal's (unfielded) I have routines to catch the process.
I am currently struggling to find the best method of implementing a traceback routine which can list the function addresses in the error log, currently my routine just prints the the signal which caused the exception and the exception qualifier code.
Any help would be greatly received, ideally I would write error handling for all processors, however at this stage I only really care about i386, and x86_64.
Thanks
Mark
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
来自
execinfo.h
的 glibc 函数backtrace()
和backtrace_symbols()
可能有用。The glibc functions
backtrace()
andbacktrace_symbols()
, fromexecinfo.h
, might be of use.您可以查看 http://tlug.up.ac.za/wiki/ index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV。它涵盖了您需要的功能。但是,您必须链接 libgdb 和 libdl,使用 -rdynamic 进行编译(在可执行文件中包含更多符号),并放弃使用某些优化。
You might look at http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV. It covers the functionality you need. However you must link against libgdb and libdl, compile with -rdynamic (includes more symbols in the executable), and forgo the use of some optimizations.
有两个 GNU(非 POSIX)函数可以帮助您 -
backtrace()
和backtrace_symbols()
- 第一个返回函数地址数组,第二个将地址解析为名称。不幸的是静态函数的名称无法解析。要使其正常工作,您需要使用
-rdynamic
标志编译二进制文件。There are two GNU (non-POSIX) functions that can help you -
backtrace()
andbacktrace_symbols()
- first returns array of function addresses and second resolves addresses to names. Unfortunately names of static functions cannot be resolved.To get it working you need to compile your binary with
-rdynamic
flag.不幸的是,没有“最佳”方法,因为堆栈的布局可能会根据 CPU、操作系统和用于编译代码的编译器而变化。但是这篇文章可能会有所帮助。
请注意,您必须在子进程中实现此功能;父进程只是收到一个出现问题的信号;您没有获得子堆栈的副本。
Unfortunately, there isn't a "best" method since the layout of the stack can vary depending on the CPU, the OS and the compiler used to compile your code. But this article may help.
Note that you must implement this in the child process; the parent process just gets a signal that something is wrong; you don't get a copy of the child stack.
如果有评论,则表明您正在使用 gcc。这个 http://gcc.gnu .org/onlinedocs/gcc-4.4.3/gcc/Return-Address.html#Return-Address 可能有用。
If a comment, you state you are using gcc. This http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Return-Address.html#Return-Address could be useful.
如果您愿意在运行 valgrind 时仅获得正确的回溯,那么这可能是您的一个选择:
VALGRIND_PRINTF_BACKTRACE(format, ...):
它将为您提供所有函数的回溯,包括静态函数。
If you're fine with only getting proper backtraces when running through valgrind, then this might be an option for you:
VALGRIND_PRINTF_BACKTRACE(format, ...):
It will give you the backtrace for all functions, including static ones.