1

The question I have is:

Is there a way to call a function or do some other work whenever a crash occurs in the program.

To be specific, the code I am currently working on gives "segmentation fault" on a very large input. This means that I am accessing some unavailable\unallocated part of the memory at some point. Displaying each step would be too nasty so I want to detect when I cross my bounds.

So how could this be done?

Muhammad Ali
  • 599
  • 1
  • 7
  • 15
  • 1
    Why not just run your code under valgrind in order to find and fix the bug(s) ? – Paul R Apr 04 '15 at 09:53
  • 2
    " I want to detect when I cross my bounds" is not related to "call a function or do some other work whenever a crash occurs". Using a debugger is good for the former. The latter is, from a C++ point of view, functionality for the regime of general Undefined Behavior, and in that regime nothing can be guaranteed by the C++ standard. For normal termination, though, including for uncaught exception, you have `std::terminate`. – Cheers and hth. - Alf Apr 04 '15 at 10:13
  • yes (I see it's kind of unix) - compile with debugging enabled (cc -g ...) then run with gdb: gdb --args ./program , then run – Peter K Apr 04 '15 at 13:30

3 Answers3

1

It is operating system and implementation specific. Practically also depends upon the compiler and optimization flags.

Very probably, you have hit some undefined behavior.

Probably valgrind should be a helpful tool.

If on Linux, read core(5) & proc(5) & signal(7). You might set up system-wide your /proc/sys/kernel/core_pattern pseudo-file to start some external program or script (perhaps starting a debugger) on core dump.

You could even handle the SIGSEGV signal in a processor- and operating-system- specific way. But I don't recommend that. See this & that answers for more.

On Linux, syscalls (listed in syscalls(2)) are nearly the only functions you can call inside a signal handler (more precisely, it is the async-signal-safe functions mentioned in signal(7) and nothing more). But a lot of library functions (including malloc & printf, fprintf, dlopen etc...) are forbidden inside signal handlers.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

If you compiled your code with debug symbols, you should be able to either load a core file into your debugger and/or attach a debugger when the crash occurs.

Usually, you can tell what happened from the location of the crash. Did you dereference a null pointer? Did you dereference an invalid pointer? The second one is harder to debug than the first (usually means memory corruption). A useful tool to use with memory corruptions, especially if the fault is repeatable, is to place "watch points" which causes the debugger to halt whenever a particular memory location (i.e. the pointer that causes the crash) changes. This will allow you to see what overwrote your pointer.

Mustafa Ozturk
  • 812
  • 4
  • 19
1

You really need a debugger. But to answer an original question for future searchers:

Yes, in UNIX you can just handle the SEGV signal with usual signal handling procedures. SIGSEGV has number 13. See this on how to handle signals.

Be aware that there are system imposed limitations on what you can do in signal handler (eg system calls are forbidden, including IO). Also if accessing your program data await that it may be corrupt. Your program will continue to work after signal handler but it is likely it steps into another error really soon.

I would not recomment to do that in production code, but I think this feature is "unix way" enough to mention on SO

Peter K
  • 1,787
  • 13
  • 15