Changeset 139


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
Files:
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/include/qt_os2.h

    r8 r139  
    4545#include <os2.h>
    4646
     47// OS/2 system exception handler callback interface
     48
     49#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
     50
     51enum QtOS2SysXcptReq
     52{
     53    QtOS2SysXcptReq_AppName = 0,
     54    QtOS2SysXcptReq_AppVer = 1,
     55    QtOS2SysXcptReq_ReportTo = 2,
     56    QtOS2SysXcptReq_ReportSubj = 3,
     57};
     58
     59typedef void (*QtOS2SysXcptWriter)( const char *str );
     60typedef int (*QtOS2SysXcptCallback)( QtOS2SysXcptReq req,
     61                                     QtOS2SysXcptWriter writer,
     62                                     int reserved );
     63
     64class Q_EXPORT QtOS2SysXcptMainHandler
     65{
     66public:
     67    QtOS2SysXcptMainHandler( QtOS2SysXcptCallback cb = NULL );
     68    ~QtOS2SysXcptMainHandler();
     69
     70    class Private;
     71   
     72private:
     73    EXCEPTIONREGISTRATIONRECORD rec;
     74   
     75    static bool installed;
     76    static QtOS2SysXcptCallback callback;
     77    static ERR libcHandler;
     78
     79    static ULONG APIENTRY handler( PEXCEPTIONREPORTRECORD pReportRec,
     80                                   PEXCEPTIONREGISTRATIONRECORD pRegRec,
     81                                   PCONTEXTRECORD pContextRec,
     82                                   PVOID pv );
     83
     84    friend class QtOS2SysXcptMainHandlerInternal;
     85    friend class QThreadInstance;
     86
     87    // these are private to allow only stack-based instances   
     88    QtOS2SysXcptMainHandler( QtOS2SysXcptMainHandler &/*that*/ ) {}
     89    QtOS2SysXcptMainHandler &operator =( QtOS2SysXcptMainHandler &/*that*/) {
     90        return *this;
     91    }
     92    static void *operator new( size_t /*size*/ ) throw() { return NULL; }
     93    static void operator delete( void */*memory*/ ) {}   
     94};
     95
     96#endif // !defined(QT_OS2_NO_SYSEXCEPTIONS)
     97
    4798#endif // QT_OS2_H
  • trunk/include/qwindowdefs_pm.h

    r136 r139  
    124124};
    125125
    126 // OS/2 system exception handler callback interface
    127 
    128 enum QtSysXcptReq
    129 {
    130     QtSysXcptReq_AppName = 0,
    131     QtSysXcptReq_AppVer = 1,
    132     QtSysXcptReq_ReportTo = 2,
    133     QtSysXcptReq_ReportSubj = 3,
    134 };
    135 
    136 typedef void (*QtSysXcptWriter)( const char *str );
    137 typedef int (*QtSysXcptCallback)( QtSysXcptReq req, QtSysXcptWriter writer,
    138                                   int reserved );
    139 
    140 Q_EXPORT QtSysXcptCallback qInstallSysXcptCallback( QtSysXcptCallback cb );
    141 
    142126#endif
  • 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 );
  • trunk/src/tools/qsysxcpt_pm.cpp

    r138 r139  
    4141 */
    4242
    43 #if !defined(QT_PM_NO_SYSEXCEPTIONS)   
     43#if !defined(QT_OS2_NO_SYSEXCEPTIONS)
    4444 
    4545#include "qt_os2.h"
     
    5959//     contexts to the trap file when a real exception happens on one thread
    6060
    61 extern ERR qt_libcExceptionHandler; // defined in qapplication_pm.cpp
    62 
    63 static QtSysXcptCallback qt_excCallback = NULL;
    64 static FILE *qt_excWriteMsg_file = NULL;
    65 
    66 static void qt_excCallbackWriter( const char *pcszMsg );
    67 
    68 /**
    69  *  Installs \a cb as the OS/2 system exception handler callback.
    70  *  Passing NULL as \a cb will uninstall the currently installed callback.
    71  *
    72  *  @todo (r=dmik) describe the callback... 
    73  */
    74 Q_EXPORT QtSysXcptCallback qInstallSysXcptCallback( QtSysXcptCallback cb )
    75 {
    76     QtSysXcptCallback tmp = qt_excCallback;
    77     qt_excCallback = cb;
    78     return tmp;
     61/*! \class QtOS2SysXcptMainHandler qt_os2.h
     62
     63    @todo (r=dmik) describe...
     64   
     65    - must be instantiated on the stack of the main thread only
     66    - must be instantiated before a QAplication instance is created
     67*/
     68
     69/* static */
     70bool QtOS2SysXcptMainHandler::installed = FALSE;
     71QtOS2SysXcptCallback QtOS2SysXcptMainHandler::callback = NULL;
     72ERR QtOS2SysXcptMainHandler::libcHandler = NULL;
     73
     74/*!
     75    @todo (r=dmik) describe...       
     76*/
     77QtOS2SysXcptMainHandler::QtOS2SysXcptMainHandler( QtOS2SysXcptCallback cb )
     78{
     79    rec.prev_structure = NULL;
     80    rec.ExceptionHandler = NULL;
     81   
     82    PTIB ptib = NULL;
     83    DosGetInfoBlocks( &ptib, NULL );
     84    Q_ASSERT( ptib && ptib->tib_ptib2 );
     85
     86    if ( ptib && ptib->tib_ptib2 )
     87    {
     88        // must be instantiated only on the main (first) thread
     89        Q_ASSERT( ptib->tib_ptib2->tib2_ultid == 1 );
     90        if ( ptib->tib_ptib2->tib2_ultid == 1 )
     91        {
     92            // must not be already instantiated
     93            Q_ASSERT( installed == FALSE );
     94            Q_ASSERT( libcHandler == NULL );
     95            if ( installed == FALSE && libcHandler == NULL )
     96            {
     97                installed = TRUE;
     98                callback = cb;
     99                // install the exception handler for the main thread
     100                rec.ExceptionHandler = handler;
     101                DosSetExceptionHandler( &rec );
     102            }
     103        }
     104    }
     105}
     106
     107/*!
     108    @todo (r=dmik) describe...       
     109*/
     110QtOS2SysXcptMainHandler::~QtOS2SysXcptMainHandler()
     111{
     112    Q_ASSERT( rec.ExceptionHandler == handler || rec.ExceptionHandler == NULL );
     113    if ( rec.ExceptionHandler == handler )
     114    {
     115        // uninstall the exception handler for the main thread
     116        DosUnsetExceptionHandler( &rec );
     117        rec.ExceptionHandler = NULL;
     118        callback = NULL;
     119        installed = FALSE;
     120    }
    79121}
    80122
    81123static void qt_excEscapeString( FILE *file, const char *pcszStr );
    82124
    83 static void qt_excCallbackWriter( const char *msg )
    84 {
    85     if ( qt_excWriteMsg_file )
    86         qt_excEscapeString( qt_excWriteMsg_file, msg );
    87 }
    88 
    89 inline int qt_excAskCallback( QtSysXcptReq req )
    90 {
    91     if ( qt_excCallback )
    92         return qt_excCallback( req, NULL, 0 );
    93     return FALSE;
    94 }
    95 
    96 inline int qt_excLetCallback( QtSysXcptReq req )
    97 {
    98     if ( qt_excCallback )
    99         return qt_excCallback( req, qt_excCallbackWriter, 0 );
    100     return FALSE;
    101 }
    102 
    103 /**
    104  *  Writes the given string with [<>&'"] characters escaped for XML.
    105  */
     125#define XcptPvt QtOS2SysXcptMainHandler::Private
     126
     127class XcptPvt
     128{
     129public:
     130    static void callbackWriter( const char *msg );
     131
     132    static inline int askCallback( QtOS2SysXcptReq req )
     133    {
     134        if ( callback )
     135            return callback( req, NULL, 0 );
     136        return FALSE;
     137    }
     138
     139    static inline int letCallback( QtOS2SysXcptReq req )
     140    {
     141        if ( callback )
     142            return callback( req, callbackWriter, 0 );
     143        return FALSE;
     144    }
     145   
     146    static FILE *file;
     147};
     148
     149/* static */
     150FILE *XcptPvt::file = NULL;
     151
     152/* static */
     153void XcptPvt::callbackWriter( const char *msg )
     154{
     155    if ( file )
     156        qt_excEscapeString( file, msg );
     157}
     158
     159/*! \internal
     160    Writes the given string with [<>&'"] characters escaped for XML.
     161*/
    106162static void qt_excEscapeString( FILE *file, const char *pcszStr )
    107163{
     
    130186}
    131187
    132 /**
    133  *  Writes the given error message.
    134  */
     188/*! \internal
     189    Writes the given error message.
     190*/
    135191static void qt_excWriteErrorMsg( FILE *file, ULONG ulIndent, const char *pcszMsg,
    136192                                 ... )
     
    147203}
    148204
    149 /**
    150  *  Writes the register name, value and optionally memory flags
    151  */
     205/*! \internal
     206    Writes the register name, value and optionally memory flags
     207*/
    152208static void qt_excWriteReg( FILE *file, const char *pszName, ULONG ulValue,
    153209                            BOOL bQueryMem = TRUE )
    154210{
    155     fprintf( file, "    <Register name=\"%s\" value=\"%08lX\"",
     211    fprintf( file, "     <Register name=\"%s\" value=\"%08lX\"",
    156212             pszName, ulValue );
    157213
     
    175231}
    176232
    177 /**
    178  *  Writes information about a signle stack frame.
    179  */
     233/*! \internal
     234    Writes information about a signle stack frame.
     235*/
    180236static void qt_excWriteStackFrame( FILE *file, ULONG ulPointer, ULONG ulAddress )
    181237{
     
    187243
    188244    if ( ulPointer )
    189         fprintf( file, "    <Frame pointer=\"%08lX\">\n", ulPointer );
     245        fprintf( file, "     <Frame pointer=\"%08lX\">\n", ulPointer );
    190246    else
    191         fprintf( file, "    <Frame pointer=\"current\">\n" );
     247        fprintf( file, "     <Frame pointer=\"current\">\n" );
    192248           
    193249    if ( ulAddress )
    194250    {
    195         fprintf( file, "     <Location address=\"%08lX\">\n", ulAddress );
     251        fprintf( file, "      <Location address=\"%08lX\">\n", ulAddress );
    196252   
    197253        arc = DosQueryModFromEIP( &hMod, &ulObject,
     
    205261        {
    206262            DosQueryModuleName( hMod, sizeof(szMod), szMod );
    207             fprintf( file, "      <Module ID=\"%04lX\" name=\"", hMod );
     263            fprintf( file, "       <Module ID=\"%04lX\" name=\"", hMod );
    208264            qt_excEscapeString( file, szMod );
    209265            fprintf( file, "\" \n"
    210                            "              segment=\"%04lX\" offset=\"%08lX\"/>\n",
     266                           "               segment=\"%04lX\" offset=\"%08lX\"/>\n",
    211267                     ulObject + 1, ulOffset );
    212268/// @todo (r=dmik) use .DBG and .SYM files to get symbols
     
    221277        qt_excWriteErrorMsg( file, 5, "Unable to access stack frame" );
    222278   
    223     fprintf( file, "     </Location>\n"
    224                    "    </Frame>\n" );
    225 }
    226 
    227 /**
    228  *  Walks the stack and writes information about stack frames.
    229  */
     279    fprintf( file, "      </Location>\n"
     280                   "     </Frame>\n" );
     281}
     282
     283/*! \internal
     284    Walks the stack and writes information about stack frames.
     285*/
    230286static void qt_excWriteStackFrames( FILE *file, PTIB ptib,
    231287                                    PCONTEXTRECORD pContextRec )
     
    233289    PULONG pulStackWord = 0;
    234290
    235     fprintf( file, "   <Frames>\n" );
     291    fprintf( file, "    <Frames>\n" );
    236292
    237293    // first the trapping address itself
     
    255311                         != (PAG_COMMIT|PAG_READ)) )
    256312            {
    257                 fprintf( file, "    <Frame pointer=\"%08lX\">\n",
     313                fprintf( file, "     <Frame pointer=\"%08lX\">\n",
    258314                         (ULONG) pulStackWord );
    259                 qt_excWriteErrorMsg( file, 5,
     315                qt_excWriteErrorMsg( file, 6,
    260316                                     "Unable to access stack frame, DosQueryMem "
    261317                                     "returned %lu and flags %08lX",
    262318                                     arc, ulFlagsPage );
    263                 fprintf( file, "    </Frame>\n" );
     319                fprintf( file, "     </Frame>\n" );
    264320                pulStackWord += 0x1000;
    265321                continue; // while
     
    271327    } // end while
    272328
    273     fprintf( file, "   </Frames>\n" );
    274 }
    275 
    276 /**
    277  *  Writes the thread information.
    278  */
     329    fprintf( file, "    </Frames>\n" );
     330}
     331
     332/*! \internal
     333    Writes the thread information.
     334*/
    279335static void qt_excWriteThreadInfo( FILE *file, PTIB ptib,
    280336                                   PEXCEPTIONREPORTRECORD pReportRec,
     
    289345    DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 );
    290346
    291     fprintf( file, " <Thread ID=\"%04lX\" slot=\"%04lX\" "
    292                             "priority=\"%04lX\" "
    293                             "mc=\"%04lX\" mcf=\"%04lX\">\n",
     347    fprintf( file, "  <Thread ID=\"%04lX\" slot=\"%04lX\" "
     348                             "priority=\"%04lX\" "
     349                             "mc=\"%04lX\" mcf=\"%04lX\">\n",
    294350             ptib->tib_ptib2->tib2_ultid, ptib->tib_ordinal, ulOldPriority,
    295351             ptib->tib_ptib2->tib2_usMCCount, ptib->tib_ptib2->tib2_fMCForceFlag );
     
    298354
    299355    fprintf( file,
    300              "  <Exception type=\"%08lX\" flags=\"%08lX\" address=\"%08lX\">\n",
     356             "   <Exception type=\"%08lX\" flags=\"%08lX\" address=\"%08lX\">\n",
    301357             pReportRec->ExceptionNum, pReportRec->fHandlerFlags,
    302358             (ULONG) pReportRec->ExceptionAddress );
     
    304360    for ( ul = 0; ul < pReportRec->cParameters;  ++ul )
    305361    {
    306         fprintf( file, "   <Param value=\"%08lX\"/>\n",
     362        fprintf( file, "    <Param value=\"%08lX\"/>\n",
    307363                 pReportRec->ExceptionInfo[ul] );
    308364    }
    309365
    310     fprintf( file, "  </Exception>\n" );
     366    fprintf( file, "   </Exception>\n" );
    311367   
    312368    // *** registers
    313369
    314     fprintf( file, "  <CPU>\n"
    315                    "   <Registers>\n" );
     370    fprintf( file, "   <CPU>\n"
     371                   "    <Registers>\n" );
    316372
    317373    if ( pContextRec->ContextFlags & CONTEXT_SEGMENTS )
     
    343399    }
    344400   
    345     fprintf( file, "   </Registers>\n"
    346                    "  </CPU>\n" );
     401    fprintf( file, "    </Registers>\n"
     402                   "   </CPU>\n" );
    347403
    348404    // *** stack
    349405
    350     fprintf( file, "  <Stack base=\"%08lX\" limit=\"%08lX\">\n",
     406    fprintf( file, "   <Stack base=\"%08lX\" limit=\"%08lX\">\n",
    351407             (ULONG) ptib->tib_pstack,
    352408             (ULONG) ptib->tib_pstacklimit );
     
    357413    }   
    358414   
    359     fprintf( file, "  </Stack>\n"
    360                    " </Thread>\n" );
     415    fprintf( file, "   </Stack>\n"
     416                   "  </Thread>\n" );
    361417   
    362418    // reset old priority
     
    366422}
    367423
    368 /**
    369  * Writes exception information to the log file.
    370  */
     424/*! \internal
     425   Writes exception information to the log file.
     426*/
    371427static void qt_excWriteException( FILE *file,
    372428                                  const char *pszExeName,
     
    382438    {
    383439        fprintf( file, " <Application name=\"" );
    384         if ( qt_excAskCallback( QtSysXcptReq_AppName ) == TRUE )
    385             qt_excLetCallback( QtSysXcptReq_AppName );
     440        if ( XcptPvt::askCallback( QtOS2SysXcptReq_AppName ) == TRUE )
     441            XcptPvt::letCallback( QtOS2SysXcptReq_AppName );
    386442        else
    387443            qt_excEscapeString( file, pszExeBase );
    388444        fprintf( file, "\" version=\"" );
    389         if ( qt_excAskCallback( QtSysXcptReq_AppVer ) == TRUE )
    390             qt_excLetCallback( QtSysXcptReq_AppVer );
     445        if ( XcptPvt::askCallback( QtOS2SysXcptReq_AppVer ) == TRUE )
     446            XcptPvt::letCallback( QtOS2SysXcptReq_AppVer );
    391447        else
    392448            fprintf( file, "unknown" );
    393449        fprintf( file, "\">\n" );
    394450
    395         if ( qt_excAskCallback( QtSysXcptReq_ReportTo ) == TRUE )
     451        if ( XcptPvt::askCallback( QtOS2SysXcptReq_ReportTo ) == TRUE )
    396452        {
    397453            fprintf( file, "  <Report to=\"" );
    398             qt_excLetCallback( QtSysXcptReq_ReportTo );
    399             if ( qt_excAskCallback( QtSysXcptReq_ReportSubj ) == TRUE )
     454            XcptPvt::letCallback( QtOS2SysXcptReq_ReportTo );
     455            if ( XcptPvt::askCallback( QtOS2SysXcptReq_ReportSubj ) == TRUE )
    400456            {
    401457                fprintf( file, "\" subject=\"" );
    402                 qt_excLetCallback( QtSysXcptReq_ReportSubj );
     458                XcptPvt::letCallback( QtOS2SysXcptReq_ReportSubj );
    403459            }
    404460            fprintf( file, "\"/>\n" );
     
    436492        qt_excWriteErrorMsg( file, 1, "ppib is NULL" );
    437493
     494        fprintf( file, " <Threads>\n" );
     495       
    438496    if ( ptib && ptib->tib_ptib2 )
    439497        qt_excWriteThreadInfo( file, ptib, pReportRec, pContextRec );
     
    442500    else
    443501        qt_excWriteErrorMsg( file, 1, "ptib->tib_ptib2 is NULL" );
     502
     503        fprintf( file, " </Threads>\n" );
    444504}
    445505
     
    544604}
    545605
    546 /**
    547  * Qt Exception handler.
    548  */
    549 ULONG APIENTRY qt_exceptionHandler( PEXCEPTIONREPORTRECORD pReportRec,
    550                                     PEXCEPTIONREGISTRATIONRECORD pRegRec,
    551                                     PCONTEXTRECORD pContextRec,
    552                                     PVOID pv )
    553 {
     606/*! \internal
     607    Qt Exception handler.
     608*/
     609/* static */
     610ULONG APIENTRY
     611QtOS2SysXcptMainHandler::handler( PEXCEPTIONREPORTRECORD pReportRec,
     612                                  PEXCEPTIONREGISTRATIONRECORD pRegRec,
     613                                  PCONTEXTRECORD pContextRec,
     614                                  PVOID pv )
     615{
     616    PTIB ptib = NULL;
     617    PPIB ppib = NULL;
     618   
    554619    /* From the VAC++3 docs:
    555620     *      "The first thing an exception handler should do is check the
     
    571636        return XCPT_CONTINUE_SEARCH;
    572637
     638    // can it ever fail?...
     639    DosGetInfoBlocks( &ptib, &ppib );
     640       
    573641    switch (pReportRec->ExceptionNum)
    574642    {
     
    585653            char szFileName[CCHMAXPATH];
    586654            FILE *file = NULL;
    587             PTIB ptib = NULL;
    588             PPIB ppib = NULL;
    589655            char szExeName[CCHMAXPATH] = "unknown";
    590656            char szExeBase[CCHMAXPATH];
    591657           
    592658            DosBeep( 880, 200 );
    593 
    594             // can it ever fail?...
    595             DosGetInfoBlocks( &ptib, &ppib );
    596659
    597660            if ( ppib )
     
    675738                         QT_VERSION_STR );
    676739
    677                 qt_excWriteMsg_file = file;
     740                XcptPvt::file = file;
    678741               
    679742                // write trap information
     
    681744                                      ppib, ptib, pReportRec, pContextRec );
    682745
    683                 qt_excWriteMsg_file = NULL;
     746                XcptPvt::file = NULL;
    684747               
    685748                fprintf( file, "</Trap>\n\n" );
     
    705768    }
    706769
    707     // we never handle the exception ourselves but let the LIBC exception
    708     // handler process it
    709     return qt_libcExceptionHandler( pReportRec, pRegRec, pContextRec, pv );
     770    // we never handle the exception ourselves
     771
     772    if ( ptib && ptib->tib_ptib2 && ptib->tib_ptib2->tib2_ultid == 1 &&
     773         QtOS2SysXcptMainHandler::libcHandler != NULL )
     774    {
     775        // we are on the main thread and were installed from qt_init() during
     776        // QApplication initialization using a hack; pass control back to the
     777        // LIBC exception handler
     778        return QtOS2SysXcptMainHandler::libcHandler( pReportRec, pRegRec,
     779                                                     pContextRec, pv );
     780    }
     781   
     782    return XCPT_CONTINUE_SEARCH;
    710783}
    711784
  • trunk/src/tools/qt_tools.pri

    r8 r139  
    9999                  $$TOOLS_CPP/qwaitcondition_pm.cpp \
    100100                  $$TOOLS_CPP/qthreadstorage_pm.cpp \
    101                   $$TOOLS_CPP/qcriticalsection_p.cpp
     101                  $$TOOLS_CPP/qcriticalsection_p.cpp \
     102                  $$TOOLS_CPP/qsysxcpt_pm.cpp
    102103
    103104        offmac:SOURCES += $$TOOLS_CPP/qdir_mac.cpp \
Note: See TracChangeset for help on using the changeset viewer.