views:

671

answers:

5
+6  Q: 

Core dump in linux

I want to create a core dump whenever my process crashes. Currently I am following this approach:

  1. Build a special "debug" version of the program using "-g" of gcc/g++.
  2. Execute "ulimit -c unlimited"
  3. 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:

  1. How to create a core dump in the "release" build of a program?
  2. Always. Without manually executing the "ulimit -c unlimited"
+1  A: 

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.

Kristof Provost
A: 

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 sniff

Edit: 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...

Hope this helps, Best regards, Tom.

tommieb75
It's important to understand that '-g' and optimization levels are completely unrelated. '-g' means that debug information will be added to the binary. It does not mean that the code will not be optimized. 'gcc -g -O3 ...' is a perfectly reasonable thing to do (with the understanding that the code might be slightly harder to debug).
Kristof Provost
Well, because sometimes crashes are very hard to reproduce. And bugs are not always predictable, right?That time I don't want to lose the information.
Sabya
Even with optimisation, a stack trace usually seems to give the right function (if not necessarily the right line). It's typically not far off. At least that's my experience.
MarkR
@Kristof: I understand that of course, but you will get the real benefit of stack trace with -g switch. Absolutely agree! It will be harder to work out... @Sabya, @MarkR: That's ok...sometimes especially processes that are daemons, are even difficult to track down the crash - starved/exhausted resources, memory, not shutting down sockets etc...Have a look at this code here...http://stackoverflow.com/questions/2177597/inputs-for-improving-code-debuggability-apart-from-logs-and-error-codes/2177725#2177725 - It might help you...
tommieb75
+11  A: 
  • Regarding the core limit, you can do it yourself in C by calling setrlimit.
  • On a GNU (glibc) or BSD system, you can get a backtrace by calling backtrace and related system calls. You will then have to translate the function addresses into function names by running addr2line (or duplicating its functionality).
  • Just don't use -g, you can still get a backtrace (except that inlined functions will not appear).
FX
+1  A: 
  1. There is no such thing as a "release" version and "debug" version on Linux. You just build a program with debugging information when use "-g". You can strip this information.

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 as assert() helps in finding bugs.

However if you don't use assert() there will be no difference.

  1. A user can set ulimit -c unlimited in his or her profile.

  2. Backtrace of an program compiled with some optimization often doesn't give a line number which is useful.

  3. 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.

  4. How to create a core dump in the "release" build of a program? It's not your responsibility, it's responsibility of the OS.

skwllsp
+1  A: 

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/