I'm compiling a C program with flags "-Wall -W -pedantic -O0 --coverage" (GCC version 4.8.2). However when a segmentation fault happens on that program I can't extract the coverage, because I don't have the .gcda file...
Does anyone know how can I use gcov even when a segmentation fault happens?
Thanks.
Does anyone know how can I use gcov even when a segmentation fault happens?
The coverage files are normally written by atexit handler, which requires program to call exit(). That does not happen when the program dies with SIGSEGV, which is why you don't get the .gcda file in that case.
The best solution is to fix whatever bug is causing SIGSEGV in the first place.
Alternatively, you could install a SIGSEGV handler, and call exit() from it. This is not guaranteed to work. For example, if your program hit SIGSEGV due to heap corruption, it may deadlock or crash again when exit calls global destructors.
Another possible solution is to run the program under GDB, and call __gcov_flush() from the debugger when you get SIGSEGV.
Related
I have written a phone book and my person input like "name-number-type" and if the user give "_" or any other character that is not "-" as seperator the program will crash by seg. fault because i used strtok() to split input. Also if the user gives number that is not proper input like 1232414eree224, my program will crash again. So i just think that if i handle the seg. fault signal in os level may be i can fix this bug. I know that i can write a controller function but i am searching for a new way to deal with like that error. Is there any possible way to do this?
So i just think that if i handle the seg. fault signal in os level may
be i can fix this bug.
It does not seem like a good idea at all, a SIGSEGV handler is not intended to ignore or try to fix the error, they are used to consistently exit your process, e.g. remove the used heap so that there are no memory leaks, to write in a log reporting the error ...
In addition, in the POSIX standard:
The behavior of a process is undefined after it returns normally from
a signal-catching function for a [XSI] SIGBUS, SIGFPE, SIGILL, or
SIGSEGV signal that was not generated by kill(), [RTS] sigqueue(), or
raise().
When running my code, it crashes and says "Segmentation fault".
However, when I run through it in gdb, it crashes due to a SIGABRT error not a SIGSEGV.
Are there other signals that also "map" to a general Segmentation fault error on the terminal?
abort() sends the calling process the SIGABRT signal, this is how SIGABRT or Signal 6 is generated. Also, most "assert" implementations make use of SIGABRT in case of a failed assert.
abort() is usually called by library functions which detect an internal error or some seriously broken constraint. For example malloc() will call abort() if its internal structures are damaged by a heap overflow.
SIGSEGV or Signal 11, officially know as "segmentation fault", means that the program accessed a memory location that was not assigned. That's usually a bug in the program. So if you're writing your own program, that's the most likely cause. otherwise I do not see any other signal will create segmentation fault in a program.
My program (it is an smtp server program, tested by jmeter) run without any problem when it is run by valgrind.
But failed (got SIGABRT) finally, if it is running without valgrind or run within 'gdb' debugger.
I've tested all of the valgrind's tools (memcheck,helgrind,drd,massif) but no one reported any problem. I haven't found any memory leaks (checked by mtrace() ).
I've got the following :
Program received signal SIGABRT, Aborted.
[Switching to Thread 0xb7101b70 (LWP 1639)]
0xb776d416 in __kernel_vsyscall ()
the backtrace show various locations which changend run by run. The problems always allude to malloc() or free() (and always correlate with a string (char array) )
The question is: how can I found the problem, if valgrind and mtrace did not show any problem and the program can run without stoppage (within valgrind) in an endless jmeter test loop?
If someone is a operating system programmer or writing a system level library code, it makes sense to write a segmentation fault handler. Like, for example, OS programmer would write code send a signal SIGSEGV to that application process. OR a systems library programmer might handle that signal SIGSEGV and may undo the operations caused by the library code for creating segmentation Fault. But why would an application programmer in C need to write segmentation fault handler? If he writes an handler, he has already corrupted some parts of memory. Can you give an instance, for an application programmer to handle segmentation fault and continue execution of the program?
AFAIK, the segmentation handler can be written at the application level, to output some debugging information (like memory dump, value of registers and other application specific information) and then exit the application.
Pls note that, since the segmentation fault might have corrupted the memory, it may or may not get all the correct information to dump.
I am not aware of any situation, where the execution of the program can be continued after a segmentation fault. May be other esteemed users of SO will be able to throw some light on this.
Handling SIGSEGV, etc, may allow saving state and taking corrective actions. Mr 32 (and others) are correct and you can not simply restart the main line code. Instead you can longjmp()siglongjmp(); this allows a re-start of the main line. Also, you have to be very careful to call async safe functions only. This is very tricky. However some applications are,
Health/saftey - to ensure a catastrophic condition doesn't happen.
Financial - loss of transaction data that can result in a loss of money.
Control system - example titration software for chemists.
Diagnostics - Crash conditions maybe logged to improve future software. As per Jay
Calling exit() is probably not good and _exit() would be better. The difference being atexit() calls.
See also: Cert async safe, Glibc async-safe list, Similar question, longjmp() and signals not portable, async-safe
These vary from OS to OS. Any advice will be system dependent!
Additional Issues
Some libraries used by the program may catch SIGSEGV. Definitely version of the Empress Database hook it. You have to know what your libraries are using and chain to/from them.
Stack and heap (malloc,etc) can be corrupted, including the jump_buf so your error handling maybe especially paranoid.
There are many other alternate solutions, such as defer critical portions to another task that is much simpler.
longjmp() called from a signal is undefined according to the C99 standard, but it will work well on most systems. siglongjmp() can be used if you are more pedantic. It would be fine for diagnostic logging, but I wouldn't use it for the other uses listed (safety, etc). Notifying a watchdog task maybe more appropriate.
You can catch any signal except SIGKILL, SIGCONT and SIGSTOP. Thus you can catch SIGSEGV, but if you decide then not to exit, the behavior will be unpredictable.
library programmer might handle that signal SIGSEGV and may
undo the operations caused by the library code for creating segmentation
segmentation fault occurs means that threads or process will be died.
You can not undo the code caused the segmentation fault. Rather you can Re-start that component.
A segmentation fault is caused by the program writing to a portion of memory it is not supposed to. The application developer does not write code to handle this, they write code to avoid it. This is why you bound check when writing to memory.
I am teaching myself to use gdb and am running some random tests. It may be worth mentioning that I am using a portable installation of MinGW on Windows 7 x64. I've created a program which I know results in a stack overflow, and as I run through it in gdb I first get two SIGSEGV signals (no surprise), and then it exits (again no surprise) with code 030000000375.
Program received signal SIGSEGV, Segmentation fault.
Program received signal SIGSEGV, Segmentation fault.
Program exited with code 030000000375.
Curiosity getting the best of me... what the heck is that code? I googled it and found very little.
Thanks!
UPDATE: For reference I tried the same program on Ubuntu, and the results are slightly different:
Program received signal SIGSEGV, Segmentation fault.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
gdb prints out the exit code in octal format. Not obvious, but indicated by the leading 0.
So 030000000375 is 0xC00000FD in hex, which makes the code look much more common to a windows programmer.
0xC00000FD is STATUS_STACK_OVERFLOW and should be defined in ntstatus.h.