Opened 18 years ago
Closed 18 years ago
#33 closed enhancement (fixed)
Add the OS/2 system exception handler to the Qt library
Reported by: | dmik | Owned by: | dmik |
---|---|---|---|
Priority: | normal | Milestone: | qt-os2-3.3.1-rc07 |
Component: | kernel | Version: | |
Severity: | normal | Keywords: | exception handler |
Cc: |
Description
We want more information about system exceptions happening in the Qt library and in applications built on top of it: the standard OS/2 popup log mechanism, as well as the kLIBC 0.6 exception handler provide not enough details (for example they don't walk the stack frames). In addition, the latter prints the exception info to stderr only, which makes little sense for release versions of PM applications.
Change History (8)
comment:1 by , 18 years ago
Status: | new → assigned |
---|
comment:2 by , 18 years ago
comment:3 by , 18 years ago
The next thing I'm going to do is to improve the exception handler so that it will print symbol information when walking the stack frames, using the debug info contained in executables/DLLs, or external .SYM files. The code will again be partly taken from the xwpheplers package (debug.h and debug.c). This will simplify debugging of hardly reproducible bugs a lot.
comment:4 by , 18 years ago
Other ideas worth implementing are:
- Synchronize the exception handler to make it capable of processing two independent simultaneous exeptions on different threads.
- Grab contexts and do stack traces of all threads of the process, not only one that caught the real exception (depends on 1). The simplest solution seems to be to raise a user-defined system exception for that purpose (but maybe it's not the best).
comment:5 by , 18 years ago
Forgot to mention that the Qt exception handler can be completely disabled by defining QT_PM_NO_SYSEXCEPTIONS when building Qt.
comment:6 by , 18 years ago
Practice shows that a QApplication instance may be created not at the very beginning of the main() function but later, after calling some other (say, static methods) inside Qt. This leaves such code unprotected against system exceptions. Therefore, I decided to introduce a special stack-based class, QtOS2SysXcptMainHandler, that can be instantiated in main() prior to creating a QApplication instance or doing something else.
The constructor of this class does two things: a) installs the exception handler for the current thread and installs an optional exception callback function (so there is no need in a separate qInstallXcptCallback API). The destructor just uninstalls the exception handler if it was installed. There are no other methods in this class. Creating an instance of this class is only meaningful on the main thread (it does nothing otherwise).
The hackish way of attaching to the existing main thread's exception handler installed by LIBC is left as is in qt_init(), however. This is to ensure that our exception handler is automatically installed in all Qt-based programs (in all programs that use QApplication, to be exact) even if the programmer doesn't do it explicitly. When both QApplication and QtOS2SysXcptMainHandler are instantiated, the one that is first wins (and the other one doesn't touch the exception handing at all).
I also realized that the exception handler has nothing to do with PM, so I moved it from the kernel module to the tools module, which also makes it possible to use in console programs that dont use QApplication at all. Therefore, all definitions were moved from qwindowdefs_pm.h to qt_os2.h. Also, the QT_PM_NO_SYSEXCEPTIONS define was renamed to QT_OS2_NO_SYSEXCEPTIONS (to reflect its non-PM nature).
comment:7 by , 18 years ago
Implemented some more functionality, in particular: querying and writing the list of all imported/loaded modules (using the DosQuerySysState() API) and grabbing the context and the call stack of all other process threads (besides the one that got an exception). Works not that bad.
The next step is to replace fprintf() and friends with the direct usage of DosWrite() and friends, for more safety (LIBC may be unstable or even screwed up when an exception happens).
comment:8 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I think it's enough with the exception handler features for now, it's already quite powerful. I'm closing the ticket at changeset:151.
I decided not to convert fprintf() to DosWrite() for now, because this exception handler is intended to catch problems in Qt and Qt-based applications in the first place (i.e. not in kLIBC itself). However, I've also got plans to create a patch for kLIBC one day that will move the implemented functionality to the kLIBC's exception handler (so that trap reports will be generated for *all* applications using kLIBC, not only Qt). That day will be the best time to do such a convertion (and more over, it's a kind of requirement, because fprintf() is itself a part of kLIBC so we can't rely on it any more if we handle exceptions there). Knut doesn't seem to mind.
I've added the experimential exception handler in changeset:136. Here are some details of the implementation.
<datetime>-<exe_name>-<nn>.xml
for filesystems supporting long file names, or just<timestamp>.xml
for ones that don't.The initial exception handler code is partly based on the except.h and except.c sources from the xwphelpers package (which is a part of the xworkplace product, see http://www.xworkplace.org, http://xworkplace.netlabs.org/ for more info). XWorkplace is Copyright (C) 1999-2002 Ulrich Moeller. Thanks, Ulrich.