Closed dmik closed 5 years ago
I found this when working on https://github.com/bitwiseworks/qtbase-os2/issues/29 — a fatal assertion on a thread started with QThread
in tst_QObject
didn't generate a .TRP file (which is nesessary to get the stack trace of that assertion).
Note that if I disable the LIBCx own exception handler (which it installs after EXCEPTQ for the needs of mmap
), then all starts working fine. So it must be that this own exception handler somehow doesn't let the EXCEPTQ handler handle the exception. Digging.
Funny enough, in the debug version of LIBCx all works. In the release build, the second exception handler in the chain (which is EXCEPTQ) does not get called if the first one (which is LIBCx for mmap) returns XCPT_CONTINUE_SEARCH straight away (no mmap code is involved). This is very strange.
I guess I know what it is. GCC re-orders stack variables in release mode. More over, it even does so if a new scope is introduced with curly braces. I.e. we have:
EXCEPTIONREGISTRATIONRECORD rec1;
{
EXCEPTIONREGISTRATIONRECORD rec2;
}
Given that the stack grows down, one would expect that the address of rec2
is smaller than the address of rec1
because the rec2
variable should be allocated on the stack after rec1
. This is true for the debug build but not for the release one. In the release one, rec1
gets a smaller address than rec2
and this apparently kills the normal exception handler chain processing.
Okay, I know how to force the compiler to maintain the right order.
FIxed above. I used a similar approach in Mozilla when it installed EXCEPTQ on its own. Note that this problem affect virtually all apps using LIBCx and creating threads with _beginthread
— in the sense that no .TRP files would be created if those threads crashed. A known issue, actually.
If a program links with LIBCx (-lcx), it should get EXCEPTQ support for the main thread as well as for all threads started with
_beginthread
. However, it doesn't seem to be the case. At least, this simple program does not generate a .TRP file:It will generate it, however, if you install EXCEPTQ manually with
[Lib]LoadExceptq
inthread_func
.