Mon 04 Apr 2005 04:42:40 PM UTC, original submission:
I've debugged bug #12323 for a view days now and found out that the real cause of this bug is the handling of null reference checks via interrupts.
Consider the following CVM code fragment which was the culprit of the segfault in bug #12323 (output stems from my debugging code):
0x4215614F: get_static Trumpf.Sys.Diagnostics.TcTrace (0x410458e8)
0x42156154: pread
0x42156155: iread_field 4
The problem here was that pread read the pointer stored at the address returned by get_static and pushed it onto the stack. Unfortunately this was a null pointer and iread_field caused a segmentation fault because the guarding BEGIN_NULL_CHECK was defined to be nothing.
And now to the interrupt handler problem: this segmentation fault is caught the first time we see this code. The signal handler executed a pnet exception handler. But the signal handler never terminates, pnet now runs in the signal handler ! This of course means the next time a segmentation fault happens the system can't call the signal handler (it's still executing) and instead kills the process.
This is what "Advanced UNIX Programming, 2nd edition" says about signal handlers:
===
"Inside the signal handler, you're restricted as to what system calls or standard funcations you can call because the signal may have occurred in a place that can't safely be re-entered. In fact, the SUS (Version 3) defines only 116 so-called async-signal-safe functions, which are listed in Table 9.1."
===
It continues to explain that not even fprintf may be called or safely refer to global variables unless they're of type volatile sig_atomic_t. Obviously, our current signal handler violates this so heavily I'm wondering why this hasn't bitten others earlier :-)
This means we have to work out a new way of how to catch errors via interrupts (which IS quite cheap and speedy). In the mean time I propose disabling the interrupt based checks on POSIX systems by default since it's better to run slow but error-free, IMHO ;-)
|