So, I have a big piece of legacy software, coded in C. It's for an embedded system, so if something goes wrong, like divide by zero, null pointer dereference, etc, there's not much to do except reboot.
I was wondering if I could implement just main() as c++ and wrap it's contents in try/catch. That way, depending on the type of exception thrown, I could log some debug info just before reboot.
Hmm, since there are multiple processes I might have to wrap each one, not just main(), but I hope that you see what I mean...
Is it worthwhile to leave the existing C code (several 100 Klocs) untouched, except for wrapping it with try/catch?
Division by zero or null pointer dereferencing don't produce exceptions (using the C++ terminology). C doesn't even have a concept of exceptions. If you are on an UNIX-like system, you might want to install signal handlers ( SIGFPE
, SIGSEGV
, etc.).
Since it's an embedded application it probably runs only on one platform.
If so its probably much simpler and less intrusive to install a proper interrupt handler / kernel trap handler for the division by zero and other hard exceptions.
In most cases this can be done with just a few lines of code. Check if the OS supports such installable exception handlers. If you're working on an OS-less system you can directly hook the CPU interrupts that are called during exceptions.
First of all, divide by zero or null pointer dereference won't throw exceptions. Fpe exceptions are implemented in the GNU C library with signals (SIGFPE). And are part of the C99 standard, not the C++ standard.
A few hints based in my experience in embedded C and C++ development. Depending on your embedded OS:
I don't think machine code compiled from C does the same thing with regard to exceptions, as machine code compiled for C++ which "knows" about exceptions. That is, I don't think it's correct to expect to be able to catch "exceptions" from C code using C++ constructs. C doesn't throw exceptions, and there's nothing that guarantees that errors that happen when C code does something bad are caught by C++'s exception mechanism.
Divide by zero, null pointer dereference are not C or C++ exceptions they are hardware exceptions.
On Windows you can get hardware exceptions like these wrapped in a normal C++ exception if _set_se_translator() is used.
__try/__catch may also help. Look up __try/__catch, GetExceptionCode(), _set_se_translator() on MSDN, you may find what you need.
I think I remember researching on how to handle SIGSEGV
( usually generated when derefing invalid pointer, or dividing by 0 ) and the general advise I found on the net was: do nothing, let the program die. The explanation, I think a correct one, is that by the time you get to a SIGSEGV trap, the stack of the offending thread is trashed beyond repair.
Can someone comment if this is true?
Only work on msvc
__try { int p = 0; p=p / 0; } __except (1) { printf("Division by 0 \n"); }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.