Changeset 139 for trunk/src/kernel


Ignore:
Timestamp:
Oct 20, 2006, 11:44:52 PM (19 years ago)
Author:
dmik
Message:

Kernel/Tools: Improved OS/2 exception handling:

  • Moved the excpetion handler code from the kernel module to the tools module (defines are now in qt_os2.h instead of qwindowdefs_pm.h);
  • QT_PM_NO_SYSEXCEPTIONS is renamed to QT_OS2_NO_SYSEXCEPTIONS;
  • Added the QtOS2SysXcptMainHandler stack-based class to correctly install the exception handler on the main thread, as well as provide an optional callback.
Location:
trunk/src/kernel
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qapplication_pm.cpp

    r136 r139  
    453453 *****************************************************************************/
    454454
    455 #if !defined(QT_PM_NO_SYSEXCEPTIONS)   
    456 extern // defined in qsysxcpt_pm.cpp
    457 ULONG APIENTRY qt_exceptionHandler( PEXCEPTIONREPORTRECORD pReportRec,
    458                                     PEXCEPTIONREGISTRATIONRECORD pRegRec,
    459                                     PCONTEXTRECORD pContextRec,
    460                                     PVOID pv );
    461 ERR qt_libcExceptionHandler = NULL;
    462 #endif
     455// wrapper for QtOS2SysXcptMainHandler to provide local access to private data
     456class QtOS2SysXcptMainHandlerInternal : public QtOS2SysXcptMainHandler
     457{
     458public:
     459    static bool &installed() { return QtOS2SysXcptMainHandler::installed; }
     460    static ERR &libcHandler() { return QtOS2SysXcptMainHandler::libcHandler; }
     461    static ERR handler() { return QtOS2SysXcptMainHandler::handler; }
     462};
     463
     464#define XcptMainHandler QtOS2SysXcptMainHandlerInternal
    463465
    464466// need to get default font?
     
    467469void qt_init( int *argcptr, char **argv, QApplication::Type )
    468470{
    469 #if !defined(QT_PM_NO_SYSEXCEPTIONS)
    470     // Since the exception registration record can only be located on the stack,
     471#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
     472    // Even if the user didn't install the exception handler for the main
     473    // thread using QtOS2SysXcptMainHandler prior to constructing a QApplication
     474    // instance, we still want it to be installed to catch system traps. But
     475    // since the exception registration record can only be located on the stack,
    471476    // we can enable our exception handling on the main thread only if the LIBC
    472477    // library of the compiler provides an exception handler (already allocated
     
    474479    // exception handler's pointer with our own (not nice but what to do?) and
    475480    // call the former (to let it do signal processing and the stuff) after we
    476     // generate the trap file. Note that if there is no LIBC exception handler
    477     // provided, qt_libcExceptionHandler will remain NULL to tell QThread not to
    478     // install our exception handler for newly created threads (all or nothing).
    479     {
    480         PTIB ptib = NULL;
    481         PPIB ppib = NULL;
    482         DosGetInfoBlocks( &ptib, &ppib );
    483        
    484         Q_ASSERT( ptib && ppib );
    485         if ( ptib && ppib ) {
     481    // generate the trap file. Note that in this tricky case, the user has no
     482    // possibility to install the exception handler callback (since it's only
     483    // possible using QtOS2SysXcptMainHandler).
     484
     485    PTIB ptib = NULL;
     486    DosGetInfoBlocks( &ptib, NULL );
     487    Q_ASSERT( ptib && ptib->tib_ptib2 );
     488   
     489    if ( ptib && ptib->tib_ptib2 ) {
     490        // must be called only on the main (first) thread
     491        Q_ASSERT( ptib->tib_ptib2->tib2_ultid == 1 );
     492        // also make sure that QtOS2SysXcptMainHandler was not already
     493        // instantiated on the main thread
     494        if ( ptib->tib_ptib2->tib2_ultid == 1 &&
     495             XcptMainHandler::installed() == FALSE )
     496        {
    486497            if ( ptib->tib_pexchain != END_OF_CHAIN ) {
    487                 PEXCEPTIONREGISTRATIONRECORD rec =
     498                PEXCEPTIONREGISTRATIONRECORD r =
    488499                    (PEXCEPTIONREGISTRATIONRECORD) ptib->tib_pexchain;
    489                 qt_libcExceptionHandler = rec->ExceptionHandler;
    490                 rec->ExceptionHandler = qt_exceptionHandler;
     500                XcptMainHandler::libcHandler() = r->ExceptionHandler;
     501                r->ExceptionHandler = XcptMainHandler::handler();
     502                XcptMainHandler::installed() = TRUE;
    491503            } else {
    492504                Q_ASSERT( 0 /* no exception handler for the main thread */ );
     
    577589//    QInputContext::shutdown();
    578590
    579 #if !defined(QT_PM_NO_SYSEXCEPTIONS)
     591#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
    580592    // remove the exception handler if it was installed in qt_init()
    581     if ( qt_libcExceptionHandler ) {
    582         PTIB ptib = NULL;
    583         PPIB ppib = NULL;
    584         DosGetInfoBlocks( &ptib, &ppib );
    585        
    586         Q_ASSERT( ptib && ppib );
    587         if ( ptib && ppib ) {
     593    PTIB ptib = NULL;
     594    DosGetInfoBlocks( &ptib, NULL );
     595    Q_ASSERT( ptib && ptib->tib_ptib2 );
     596   
     597    if ( ptib && ptib->tib_ptib2 ) {
     598        // must be called only on the main (first) thread
     599        Q_ASSERT( ptib->tib_ptib2->tib2_ultid == 1 );
     600        // also make sure the handler was really installed by qt_init()
     601        if ( ptib->tib_ptib2->tib2_ultid == 1 &&
     602             XcptMainHandler::installed() == TRUE &&
     603             XcptMainHandler::libcHandler() != NULL )
     604        {
    588605            Q_ASSERT( ptib->tib_pexchain != END_OF_CHAIN );
    589606            if ( ptib->tib_pexchain != END_OF_CHAIN ) {
    590                 PEXCEPTIONREGISTRATIONRECORD rec =
     607                PEXCEPTIONREGISTRATIONRECORD r =
    591608                    (PEXCEPTIONREGISTRATIONRECORD) ptib->tib_pexchain;
    592                 Q_ASSERT( rec->ExceptionHandler == qt_exceptionHandler );
    593                 if ( rec->ExceptionHandler == qt_exceptionHandler ) {
    594                     rec->ExceptionHandler = qt_libcExceptionHandler;
    595                     qt_libcExceptionHandler = NULL;
     609                Q_ASSERT( r->ExceptionHandler == XcptMainHandler::handler() );
     610                if ( r->ExceptionHandler == XcptMainHandler::handler() ) {
     611                    r->ExceptionHandler = XcptMainHandler::libcHandler();
     612                    XcptMainHandler::libcHandler() = NULL;
     613                    XcptMainHandler::installed() = FALSE;
    596614                }
    597615            }
  • trunk/src/kernel/qt_kernel.pri

    r136 r139  
    140140                  $$KERNEL_CPP/qthread_pm.cpp \
    141141                  $$KERNEL_CPP/qwidget_pm.cpp \
    142                   $$KERNEL_CPP/qfontengine_pm.cpp \
    143                   $$KERNEL_CPP/qsysxcpt_pm.cpp
     142                  $$KERNEL_CPP/qfontengine_pm.cpp
    144143
    145144        unix:x11 {
  • trunk/src/kernel/qthread_pm.cpp

    r136 r139  
    3939
    4040#include "qt_os2.h"
    41 
    42 #if !defined(QT_PM_NO_SYSEXCEPTIONS)
    43 extern // defined in qsysxcpt_pm.cpp
    44 ULONG APIENTRY qt_exceptionHandler( PEXCEPTIONREPORTRECORD pReportRec,
    45                                     PEXCEPTIONREGISTRATIONRECORD pRegRec,
    46                                     PCONTEXTRECORD pContextRec,
    47                                     PVOID pv );
    48 extern ERR qt_libcExceptionHandler; // defined in qapplication_pm.cpp
    49 #endif
    5041
    5142#include "qthread.h"
     
    115106    LocalStorage = arg [1];
    116107
    117 #if !defined(QT_PM_NO_SYSEXCEPTIONS)
    118     // don't set the exception handler if not able to do it for main thread
    119     bool setException = qt_libcExceptionHandler != NULL;
    120     EXCEPTIONREGISTRATIONRECORD excRegRec = { 0, qt_exceptionHandler };
     108#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
     109    // don't set the exception handler if not able to do it for the main thread
     110    bool setException = QtOS2SysXcptMainHandler::installed;
     111    EXCEPTIONREGISTRATIONRECORD excRegRec =
     112        { 0, QtOS2SysXcptMainHandler::handler };
    121113    if ( setException )
    122114        DosSetExceptionHandler( &excRegRec );
     
    127119    finish( (QThreadInstance *) arg[1] );
    128120
    129 #if !defined(QT_PM_NO_SYSEXCEPTIONS)
     121#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
    130122    if ( setException )
    131123        DosUnsetExceptionHandler( &excRegRec );
Note: See TracChangeset for help on using the changeset viewer.