Linux 中的核心转储
每当我的进程崩溃时,我想创建一个核心转储。目前我正在遵循这种方法:
- 使用 gcc/g++ 的“-g”构建程序的特殊“调试”版本。
- 执行“ulimit -c unlimited”
- 现在,只要程序崩溃,我们就会得到核心转储。
但我想尽量减少步骤数,以便:
- 核心转储应该始终被创建。即使它是“发布”版本。不应要求用户手动执行命令“
ulimit -c unlimited
”。 - 该核心转储的回溯应该能够给出调用的文件、函数、行号。这是人类可读形式的堆栈跟踪。
- 我不想使用“-g”将程序构建为调试版本。或者至少它不应该包含生成人类可读的堆栈跟踪所不需要的任何其他调试信息。因为这将是该程序的发布版本。
所以我有两个问题:
- 如何在程序的“发布”版本中创建核心转储?
- 总是。无需手动执行“
ulimit -c unlimited
”
I want to create a core dump whenever my process crashes. Currently I am following this approach:
- Build a special "debug" version of the program using "-g" of gcc/g++.
- Execute "ulimit -c unlimited"
- Now we get the core dump whenever the program crashes.
But I want to minimize the number of steps so that:
- Core dump should always get created. Even if it is "release" build. The user should not be asked to execute the command "
ulimit -c unlimited
" manually. - That core dump's backtrace should be able to give the file, function, line number of the calls. That is stack trace in a human readable form.
- I don't want to build the program as a debug build with "-g". Or at least it shouldn't contain any other debugging information which is not required to produce the human readable stack trace. Because this would be a release build of the program.
So I have two questions:
- How to create a core dump in the "release" build of a program?
- Always. Without manually executing the "
ulimit -c unlimited
"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
setrlimit
< /a>.backtrace
以及相关的系统调用。然后,您必须通过运行 addr2line (或复制其功能)将函数地址转换为函数名称。-g
,您仍然可以获得回溯(除了不会出现内联函数)。setrlimit
.backtrace
and related system calls. You will then have to translate the function addresses into function names by runningaddr2line
(or duplicating its functionality).-g
, you can still get a backtrace (except that inlined functions will not appear).通常的解决方案是使用 -g 进行构建,并在发布文件之前删除调试信息。寻找“strip”命令。
您可以保留带有调试信息的文件,并使用它来调试从客户那里获得的核心转储。
如果您想在用户计算机上打印人类可读的回溯,您需要分发带有(一些)调试信息的二进制文件。
在 glibc 中查找“backtrace()”函数。
请注意,即使您的二进制文件不包含调试信息,也会创建核心转储(如果正确设置了 ulimit)。
确保创建核心转储的最佳方法可能是从脚本执行二进制文件,该脚本在运行二进制文件之前设置 ulimit。
The usual solution is to build with -g and to strip off the debug information before releasing the file. Look for the 'strip' command.
You keep the file with debug information and use it to debug core dumps you get from customers.
If you want to print the human readable backtrace on the users machine you'll need to distribute binaries with (some) debug information.
Look for the 'backtrace()' function in glibc.
Note that core dumps will be created (if ulimit is set appropriately) even if your binary doesn't contain debug information.
The best way to ensure the creation of a core dump is probably to execute your binary from a script which sets ulimit before running the binary.
您可以尝试 google-coredumper:
一个简洁的工具,用于在程序运行时从多线程应用程序创建 GDB 可读的核心转储。 coredumper 库可以编译到应用程序中以创建正在运行的程序的核心转储,而无需终止。
http://sourceforge.net/projects/goog-coredumper/
You can try google-coredumper:
A neat tool for creating GDB readable coredumps from multithreaded applications -- while the program is running. The coredumper library can be compiled into applications to create core dumps of the running program, without terminating.
http://sourceforge.net/projects/goog-coredumper/
已更新
实际上,我认为我应该谈谈我在消息中没有提到的调试版本和发布版本之间可能存在的差异。发布版本可能会使用 NDEBUG 定义来构建,以便消除程序中的所有
assert()
。相反,调试版本应该在不定义 NDEBUG 的情况下构建,因为assert()
有助于查找错误。但是,如果您不使用
assert()
,则不会有任何区别。用户可以在其个人资料中设置 ulimit -c unlimited。
使用某些优化编译的程序的回溯通常不会给出有用的行号。
您可以构建一个带有调试信息的版本并将其放入您的存档中。然后剥离它并将剥离的二进制文件交付给您的客户。如果客户给您一个核心文件,那么只需使用带有调试信息的版本和客户提供的核心文件即可。
如何在程序的“发布”版本中创建核心转储?
这不是您的责任,而是操作系统的责任。Updated
Actually I think I should say about one possible difference between debug and release versions that I didn't mention in my message. Release versions might be built with the NDEBUG define in order to get rid of all
assert()
in the program. Debug versions on the contrary should be built without defining NDEBUG asassert()
helps in finding bugs.However if you don't use
assert()
there will be no difference.A user can set ulimit -c unlimited in his or her profile.
Backtrace of an program compiled with some optimization often doesn't give a line number which is useful.
You can build a version with debugging information and put in your archive. Then strip it and deliver the stripped binaries to your customers. If a customer gives you a core file then just use the version with debugging information and the core file from the customer.
How to create a core dump in the "release" build of a program?
It's not your responsibility, it's responsibility of the OS.如果代码是发布模式/高度优化的版本,您将很难以人类形式获得像样的堆栈跟踪。使用 -g 开关或者完全忘记进行堆栈跟踪......你不能两者兼得!这又回到了这一点——听起来你预计代码即使在生产环境中也会崩溃???
为什么不先修复代码并确保它能正常工作
...代码有味道...嗅嗅编辑: 好的,我我上面的评论可能有点严厉,我无意在那里严厉......为了读者的利益,我在此处添加了指向此处发布的另一个问题的链接,其中 我给出的答案,使用信号来创建堆栈跟踪并重定向到文件。这将对OP的问题有所帮助,并帮助他解决问题......
You will hardly get a decent stacktrace in human form if the code is a release mode/highly optimized version. Use the -g switch or forget about doing a stacktrace altogether...you cannot have both!! Which brings back to this point - it sounds like you are anticipating the code to crash even in production environment???
Why don't you fix the code and ensure it works first
...code smells .... sniff sniffEdit: Ok, I may have come across a bit harsh in my comment above, I did not intend to be harsh there...for the benefit of the readers, I have included a link to another question posted here, and in that answer I gave, uses signals to create a stack-trace and redirect to a file. It will be of help to the OP's question and aid him in troubleshooting...