LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   [C++] How to log the segmentation faults/errors (which crash the program) by remote logging library? (https://www.linuxquestions.org/questions/programming-9/%5Bc-%5D-how-to-log-the-segmentation-faults-errors-which-crash-the-program-by-remote-logging-library-943854/)

Aquarius_Girl 05-08-2012 05:02 AM

[C++] How to log the segmentation faults/errors (which crash the program) by remote logging library?
 
What is the technique to log the segmentation faults and
run time errors which crash the program, through a
"remote logging library"?

The language is C++.

Ajit Gunge 05-08-2012 06:17 AM

Are you asking how coredump files are generated?

Aquarius_Girl 05-08-2012 06:24 AM

My question is about how to send the relevant info
about the seg fault through a "remote logging library".

Nominal Animal 05-08-2012 09:49 AM

It is possible to catch segmentation faults and bus errors in the process itself by installing SIGSEGV and SIGBUS signal handlers. They are extremely tricky to write correctly, but it is possible. They cannot be used to fix any problems, though; the process is already dying when the signals are caught.

While you can use write() and send() and their variants in a signal handler (and even open(), socket(), connect() and so on; see Async-signal-safe functions section in man 7 signal for complete listing), you need to be extremely careful. All dynamic memory structures may be shot at this point (except for addresses to static and global variables, and parameters to the signal handler). Especially C and C++ libraries' internal data structures get mangled very easily, so you just cannot rely on them at all! To obtain information about the problem, set the SA_SIGINFO flag when installing the handlers. Also, I'd recommend setting up an alternate stack, too, because the default stack may be completely shot also. Because you cannot rely on any library function to work, your code should use syscalls directly. You might also wish to use an atomically modified global variable to see if the fault handler has already been executed, and if so, explicitly exit: in some cases the signal handler may end up being called in an endless loop.

Indeed, I think you'd absolutely have to write the signal handler code in C, because otherwise the C++ runtime might foil your attempt anyway. (Even C-looking code tends to use C++ runtime under the hood; if the C++ runtime state is shot, then even basic C++ code is likely to fail to work.) Simply write these handlers in C, and use signaturevoid __attribute__ ((constructor)) my_initialization_function(void) for the initialization function, so that it is automatically called when the library is dynamically loaded (or if statically compiled, before main() is executed). But, like I said, this is very hard to do right, and all you might get extra is a pointer to the memory location causing the problem.

If adding such code into a process or library is not feasible, you can do something very similar by using a process supervisor (similar to e.g. daemontools or runit); a parent process to the actual supervised process. In that case the supervised process usually logs to standard output, and the supervisor transmits the log to the remote end. If the supervised process exits or dies, the parent==supervisor will be sent a SIGCHLD signal, and reaping the supervised process using wait() or waitpid() will be able to determine the reason by checking the result using the WIFSIGNALED() and WTERMSIG() macros. WCOREDUMP() will tell if there is a core dump, so I guess it would be possible for the supervisor to check the core dump (if available) for the details of the demise of the supervised process, but otherwise the supervisor process only knows why the process died, not which code or memory location caused the death.


All times are GMT -5. The time now is 06:22 PM.