- Timestamp:
- Oct 29, 2006, 6:21:57 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/tools/qsysxcpt_pm.cpp
r145 r146 64 64 65 65 - must be instantiated on the stack of the main thread only 66 - mustbe instantiated before a QAplication instance is created66 - should be instantiated before a QAplication instance is created 67 67 (does nothing otherwise) 68 - note that callback can be called on any thread 68 69 */ 69 70 … … 252 253 APIRET arc = NO_ERROR; 253 254 HMODULE hMod = NULLHANDLE; 254 char szMod[CCHMAXPATH] = "unknown";255 char szMod[CCHMAXPATH] = ""; 255 256 ULONG ulObject = 0, 256 257 ulOffset = 0; 257 258 258 if ( ulPointer)259 fprintf ( file, " <Frame pointer=\"%08lX\">\n", ulPointer);259 if (ulPointer) 260 fprintf (file, " <Frame pointer=\"%08lX\">\n", ulPointer); 260 261 else 261 fprintf ( file, " <Frame pointer=\"current\">\n");262 263 fprintf ( file, " <Location address=\"%08lX\">\n", ulAddress);264 265 arc = DosQueryModFromEIP (&hMod, &ulObject,266 sizeof (szMod), szMod, &ulOffset,267 ulAddress 262 fprintf (file, " <Frame pointer=\"current\">\n"); 263 264 fprintf (file, " <Location address=\"%08lX\">\n", ulAddress); 265 266 arc = DosQueryModFromEIP (&hMod, &ulObject, 267 sizeof (szMod), szMod, &ulOffset, 268 ulAddress); 268 269 269 270 if (arc != NO_ERROR) 270 qt_excWriteErrorMsg (file, 7, "%s: DosQueryModFromEIP returned %lu",271 szMod, arc 271 qt_excWriteErrorMsg (file, 7, "%s: DosQueryModFromEIP returned %lu", 272 szMod, arc); 272 273 else 273 274 { 274 DosQueryModuleName( hMod, sizeof(szMod), szMod ); 275 fprintf( file, " <Module ID=\"%04lX\" name=\"", hMod ); 276 qt_excEscapeString( file, szMod ); 277 fprintf( file, "\" \n" 278 " segment=\"%04lX\" offset=\"%08lX\"/>\n", 279 ulObject + 1, ulOffset ); 280 /// @todo (r=dmik) use .DBG and .SYM files to get symbols 281 // (see debug.h and debug.c from the xwphelpers package) 282 // dbgPrintStackFrame(file, 283 // szFullName, 284 // ulObject, 285 // ulOffset); 275 fprintf (file, " <Module ID=\"%04lX\" segment=\"%04lX\" " 276 "offset=\"%08lX\"/>\n", 277 hMod, ulObject + 1, ulOffset); 286 278 } 287 279 … … 293 285 ULONG ulFlags = 0; 294 286 APIRET arc = NO_ERROR; 295 while ( 1)296 { 297 arc = DosQueryMem ( (void *) (ULONG) pch, &ulCount, &ulFlags);298 if ( arc == NO_ERROR)299 { 300 if ( ulCount >= enmDelta * 2)287 while (1) 288 { 289 arc = DosQueryMem ((void *) (ULONG) pch, &ulCount, &ulFlags); 290 if (arc == NO_ERROR) 291 { 292 if (ulCount >= enmDelta * 2) 301 293 break; 302 if ( pch + ulCount <= (UCHAR *) ulAddress ) 303 { // ulAddress is outside the pch object 294 if (pch + ulCount <= (UCHAR *) ulAddress) 295 { 296 /* ulAddress is outside the pch object */ 304 297 pch += ulCount; 305 298 ulCount = enmDelta * 2 - ulCount; 306 299 } 307 300 else 308 { // ulAddress is within the pch object 301 { 302 /* ulAddress is within the pch object */ 309 303 pchEnd = pch += ulCount; 310 304 break; 311 305 } 312 306 } 313 else if ( arc == ERROR_INVALID_ADDRESS)314 { 315 if ( ((ULONG) pch) & 0xFFFFF000 == ulAddress & 0xFFFFF000)316 break; / / the same page, ulAddress inaccessible307 else if (arc == ERROR_INVALID_ADDRESS) 308 { 309 if (((ULONG) pch) & 0xFFFFF000 == ulAddress & 0xFFFFF000) 310 break; /* the same page, ulAddress inaccessible */ 317 311 pch = (UCHAR *) (ulAddress & 0xFFFFF000); 318 312 } 319 313 } 320 fprintf ( file, " <Dump address=\"%08lX\">\n ", pch);321 if ( 322 ulFlags & (PAG_COMMIT|PAG_READ) == (PAG_COMMIT | PAG_READ))323 { 324 for ( ; pch < pchEnd; ++pch)325 fprintf (file, "%02lX%c", (ULONG) *pch,326 ulAddress - (ULONG) pch == 1 ? '-' : ' ' 327 fprintf ( file, "\n");314 fprintf (file, " <Dump address=\"%08lX\">\n ", pch); 315 if (arc == NO_ERROR && 316 ulFlags & (PAG_COMMIT|PAG_READ) == (PAG_COMMIT | PAG_READ)) 317 { 318 for (; pch < pchEnd; ++pch) 319 fprintf (file, "%02lX%c", (ULONG) *pch, 320 ulAddress - (ULONG) pch == 1 ? '-' : ' '); 321 fprintf (file, "\n"); 328 322 } 329 323 else 330 qt_excWriteErrorMsg (file, 0, "%08lX: DosQueryMem returned %lu"331 "and flags %08lX", pch, arc, ulFlags 332 fprintf ( file, " </Dump>\n");333 } 334 335 fprintf (file, " </Location>\n"336 " </Frame>\n" 324 qt_excWriteErrorMsg (file, 0, "%08lX: DosQueryMem returned %lu" 325 "and flags %08lX", pch, arc, ulFlags); 326 fprintf (file, " </Dump>\n"); 327 } 328 329 fprintf (file, " </Location>\n" 330 " </Frame>\n"); 337 331 } 338 332 … … 340 334 Walks the stack and writes information about stack frames. 341 335 */ 342 static void qt_excWriteStackFrames (FILE *file, PTIB ptib,343 PCONTEXTRECORD pContextRec 336 static void qt_excWriteStackFrames (FILE *file, PTIB ptib, 337 PCONTEXTRECORD pContextRec) 344 338 { 345 339 PULONG pulStackWord = 0; 346 340 347 fprintf ( file, " <Frames>\n");348 349 / / first the trapping address itself350 qt_excWriteStackFrame ( file, 0, pContextRec->ctx_RegEip);341 fprintf (file, " <Frames>\n"); 342 343 /* first the trapping address itself */ 344 qt_excWriteStackFrame (file, 0, pContextRec->ctx_RegEip); 351 345 352 346 pulStackWord = (PULONG) pContextRec->ctx_RegEbp; 353 347 354 while ( 355 && pulStackWord < (PULONG) ptib->tib_pstacklimit)356 { 357 if ( ((ULONG) pulStackWord & 0x00000FFF) == 0x00000000)358 { 359 / / we're on a page boundary: check access348 while ( pulStackWord != 0 349 && pulStackWord < (PULONG) ptib->tib_pstacklimit) 350 { 351 if (((ULONG) pulStackWord & 0x00000FFF) == 0x00000000) 352 { 353 /* we're on a page boundary: check access */ 360 354 ULONG ulCount = 0x1000; 361 355 ULONG ulFlags = 0; 362 APIRET arc = DosQueryMem ((void *) pulStackWord,363 &ulCount, &ulFlags 364 if ( 365 366 367 != (PAG_COMMIT|PAG_READ)))368 { 369 fprintf (file, " <Frame pointer=\"%08lX\">\n",370 (ULONG) pulStackWord 371 qt_excWriteErrorMsg (file, 6, "DosQueryMem returned %lu "372 "and flags %08lX", arc, ulFlags 373 fprintf ( file, " </Frame>\n");356 APIRET arc = DosQueryMem ((void *) pulStackWord, 357 &ulCount, &ulFlags); 358 if ( (arc != NO_ERROR) 359 || ( arc == NO_ERROR 360 && (ulFlags & (PAG_COMMIT|PAG_READ)) 361 != (PAG_COMMIT|PAG_READ))) 362 { 363 fprintf (file, " <Frame pointer=\"%08lX\">\n", 364 (ULONG) pulStackWord); 365 qt_excWriteErrorMsg (file, 6, "DosQueryMem returned %lu " 366 "and flags %08lX", arc, ulFlags); 367 fprintf (file, " </Frame>\n"); 374 368 pulStackWord += 0x1000; 375 continue; / / while376 } 377 } 378 379 qt_excWriteStackFrame ( file, (ULONG) pulStackWord, *(pulStackWord + 1));369 continue; /* while */ 370 } 371 } 372 373 qt_excWriteStackFrame (file, (ULONG) pulStackWord, *(pulStackWord + 1)); 380 374 pulStackWord = (PULONG) *(pulStackWord); 381 } / / end while382 383 fprintf ( file, " </Frames>\n");375 } /* end while */ 376 377 fprintf (file, " </Frames>\n"); 384 378 } 385 379 386 380 /*! \internal 387 381 Writes the thread information. 388 */ 389 static void qt_excWriteThreadInfo( FILE *file, PTIB ptib, 390 PEXCEPTIONREPORTRECORD pReportRec, 391 PCONTEXTRECORD pContextRec ) 392 { 393 ULONG ul = 0; 394 ULONG ulOldPriority = ~0; 395 396 // raise this thread's priority, because this 397 // might take some time 398 ulOldPriority = ptib->tib_ptib2->tib2_ulpri; 399 DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 ); 400 401 fprintf( file, " <Thread ID=\"%04lX\" slot=\"%04lX\" " 402 "priority=\"%04lX\" " 403 "mc=\"%04lX\" mcf=\"%04lX\">\n", 404 ptib->tib_ptib2->tib2_ultid, ptib->tib_ordinal, ulOldPriority, 405 ptib->tib_ptib2->tib2_usMCCount, ptib->tib_ptib2->tib2_fMCForceFlag ); 406 407 // *** generic exception info 408 409 fprintf( file, 410 " <Exception type=\"%08lX\" flags=\"%08lX\" address=\"%08lX\">\n", 411 pReportRec->ExceptionNum, pReportRec->fHandlerFlags, 412 (ULONG) pReportRec->ExceptionAddress ); 413 414 for ( ul = 0; ul < pReportRec->cParameters; ++ul ) 415 { 416 fprintf( file, " <Param value=\"%08lX\"/>\n", 417 pReportRec->ExceptionInfo[ul] ); 418 } 419 420 fprintf( file, " </Exception>\n" ); 421 422 // *** registers 423 424 fprintf( file, " <CPU>\n" 425 " <Registers>\n" ); 426 427 if ( pContextRec->ContextFlags & CONTEXT_SEGMENTS ) 428 { 429 qt_excWriteReg( file, "DS", pContextRec->ctx_SegDs, FALSE ); 430 qt_excWriteReg( file, "ES", pContextRec->ctx_SegEs, FALSE ); 431 qt_excWriteReg( file, "FS", pContextRec->ctx_SegFs, FALSE ); 432 qt_excWriteReg( file, "GS", pContextRec->ctx_SegGs, FALSE ); 433 } 434 435 if ( pContextRec->ContextFlags & CONTEXT_INTEGER ) 436 { 437 qt_excWriteReg( file, "EAX", pContextRec->ctx_RegEax ); 438 qt_excWriteReg( file, "EBX", pContextRec->ctx_RegEbx ); 439 qt_excWriteReg( file, "ECX", pContextRec->ctx_RegEcx ); 440 qt_excWriteReg( file, "EDX", pContextRec->ctx_RegEdx ); 441 qt_excWriteReg( file, "ESI", pContextRec->ctx_RegEsi ); 442 qt_excWriteReg( file, "EDI", pContextRec->ctx_RegEdi ); 443 } 444 445 if ( pContextRec->ContextFlags & CONTEXT_CONTROL ) 446 { 447 qt_excWriteReg( file, "CS", pContextRec->ctx_SegCs, FALSE ); 448 qt_excWriteReg( file, "EIP", pContextRec->ctx_RegEip ); 449 qt_excWriteReg( file, "SS", pContextRec->ctx_SegSs, FALSE ); 450 qt_excWriteReg( file, "ESP", pContextRec->ctx_RegEsp ); 451 qt_excWriteReg( file, "EBP", pContextRec->ctx_RegEbp ); 452 qt_excWriteReg( file, "EFLAGS", pContextRec->ctx_EFlags, FALSE ); 453 } 454 455 fprintf( file, " </Registers>\n" 456 " </CPU>\n" ); 457 458 // *** stack 459 460 fprintf( file, " <Stack base=\"%08lX\" limit=\"%08lX\">\n", 382 If ptib is not NULL, the current thread's information is to be written. 383 If ptib is NULL, pThrdRec is guaranted not to be NULL. 384 */ 385 static void qt_excWriteThreadInfo (FILE *file, PTIB ptib, QSTREC *pThrdRec, 386 PCONTEXTRECORD pContextRec) 387 { 388 if (ptib) 389 { 390 fprintf (file, " <Thread ID=\"%04lX\" slot=\"%04lX\" " 391 "priority=\"%04lX\" ", 392 ptib->tib_ptib2->tib2_ultid, ptib->tib_ordinal, 393 ptib->tib_ptib2->tib2_ulpri); 394 if (pThrdRec) 395 fprintf (file, "state=\"%02lX\" ", (ULONG) pThrdRec->state); 396 fprintf (file, "mc=\"%04lX\" mcf=\"%04lX\">\n", 397 ptib->tib_ptib2->tib2_usMCCount, 398 ptib->tib_ptib2->tib2_fMCForceFlag); 399 } 400 else 401 { 402 fprintf (file, " <Thread ID=\"%04lX\" slot=\"%04lX\" " 403 "priority=\"%04lX\" state=\"%02lX\">\n", 404 pThrdRec->tid, pThrdRec->slot, pThrdRec->priority, 405 pThrdRec->state); 406 } 407 408 /* *** registers */ 409 410 fprintf (file, " <CPU>\n" 411 " <Registers>\n"); 412 413 if (pContextRec->ContextFlags & CONTEXT_SEGMENTS) 414 { 415 qt_excWriteReg (file, "DS", pContextRec->ctx_SegDs, FALSE); 416 qt_excWriteReg (file, "ES", pContextRec->ctx_SegEs, FALSE); 417 qt_excWriteReg (file, "FS", pContextRec->ctx_SegFs, FALSE); 418 qt_excWriteReg (file, "GS", pContextRec->ctx_SegGs, FALSE); 419 } 420 421 if (pContextRec->ContextFlags & CONTEXT_INTEGER) 422 { 423 qt_excWriteReg (file, "EAX", pContextRec->ctx_RegEax); 424 qt_excWriteReg (file, "EBX", pContextRec->ctx_RegEbx); 425 qt_excWriteReg (file, "ECX", pContextRec->ctx_RegEcx); 426 qt_excWriteReg (file, "EDX", pContextRec->ctx_RegEdx); 427 qt_excWriteReg (file, "ESI", pContextRec->ctx_RegEsi); 428 qt_excWriteReg (file, "EDI", pContextRec->ctx_RegEdi); 429 } 430 431 if (pContextRec->ContextFlags & CONTEXT_CONTROL) 432 { 433 qt_excWriteReg (file, "CS", pContextRec->ctx_SegCs, FALSE); 434 qt_excWriteReg (file, "EIP", pContextRec->ctx_RegEip); 435 qt_excWriteReg (file, "SS", pContextRec->ctx_SegSs, FALSE); 436 qt_excWriteReg (file, "ESP", pContextRec->ctx_RegEsp); 437 qt_excWriteReg (file, "EBP", pContextRec->ctx_RegEbp); 438 qt_excWriteReg (file, "EFLAGS", pContextRec->ctx_EFlags, FALSE); 439 } 440 441 fprintf (file, " </Registers>\n" 442 " </CPU>\n"); 443 444 /* *** stack */ 445 446 fprintf (file, " <Stack base=\"%08lX\" limit=\"%08lX\">\n", 461 447 (ULONG) ptib->tib_pstack, 462 (ULONG) ptib->tib_pstacklimit 463 464 if ( pContextRec->ContextFlags & CONTEXT_CONTROL)465 { 466 qt_excWriteStackFrames ( file, ptib, pContextRec);448 (ULONG) ptib->tib_pstacklimit); 449 450 if (pContextRec->ContextFlags & CONTEXT_CONTROL) 451 { 452 qt_excWriteStackFrames (file, ptib, pContextRec); 467 453 } 468 454 469 fprintf( file, " </Stack>\n" 470 " </Thread>\n" ); 471 472 // reset old priority 473 DosSetPriority( PRTYS_THREAD, (ulOldPriority & 0x0F00) >> 8, 474 (UCHAR) ulOldPriority, 475 0 ); 455 fprintf (file, " </Stack>\n" 456 " </Thread>\n"); 457 } 458 459 typedef struct _PROCESSINFO 460 { 461 /* common values */ 462 char *pszFullName; 463 char *pszBaseName; 464 /* direct info pointers */ 465 PPIB ppib; 466 PTIB ptib; 467 BOOL bHaveSysState; /**< TRUE when both pProcRec and pLibRec are not NULL */ 468 QSPREC *pProcRec; /**< NULL when bHaveSysState is FALSE */ 469 QSLREC *pLibRec; /**< NULL when bHaveSysState is FALSE */ 470 } PROCESSINFO; 471 472 /*! \internal 473 Writes module information to the log file. 474 \a ulOrigin is 1 (self), 2 (imported), or 3 (loaded). Other values are 475 ignored. 476 */ 477 static void qt_excWriteModule (FILE *file, USHORT hmte, char *pszName, 478 ULONG ulOrigin = 0) 479 { 480 static const char *apszOrigins[] = { "self", "imported", "loaded" }; 481 482 fprintf (file, " <Module ID=%\"%04lX\" name=\"", hmte); 483 qt_excEscapeString (file, pszName); 484 if (ulOrigin >= 1 && ulOrigin <= 3) 485 fprintf (file, "\"\n" 486 " origin=\"%s\"/>\n", 487 apszOrigins [ulOrigin - 1]); 488 else 489 fprintf (file, "\"/>\n"); 490 } 491 492 /*! \internal 493 Writes module and all its imports information to the log file. 494 \a ulOrigin is 1 (self), or 3 (loaded), other values are ignored. 495 */ 496 static void qt_excWriteModules (FILE *file, USHORT hmte, QSLREC *pFirstLibRec, 497 ULONG ulOrigin) 498 { 499 QSLREC *pLibRec = pFirstLibRec; 500 while (pLibRec) 501 { 502 if (pLibRec->hmte == hmte && 503 pLibRec->pName /* not yet visited */) 504 { 505 qt_excWriteModule (file, hmte, (char *) pLibRec->pName, ulOrigin); 506 /* mark as visited */ 507 pLibRec->pName = NULL; 508 /* go through imports */ 509 if (pLibRec->ctImpMod) 510 { 511 USHORT *pHmte = (USHORT *) (pLibRec + 1); 512 for (ULONG i = 0; i < pLibRec->ctImpMod; ++ i, ++ pHmte) 513 qt_excWriteModules (file, *pHmte, pFirstLibRec, 514 ulOrigin == 1 ? 2 : ulOrigin); 515 break; 516 } 517 } 518 pLibRec = (QSLREC *) pLibRec->pNextRec; 519 } 520 } 521 522 /** Struct for recursive qt_excWriteModulesOnStack() to reduce stack usage */ 523 typedef struct _WMOS_STATE 524 { 525 FILE *file; 526 ULONG ulRegEbp; 527 ULONG ulRegEip; 528 ULONG ulStackLimit; 529 USHORT hmteExe; 530 ULONG cLevel; 531 USHORT *pHmteOuter; 532 } WMOS_STATE; 533 534 /*! \internal 535 Walks the stack and writes information about all encountered modules. 536 Used only when DosQuerySysState() fails (so qt_excWriteModules() is not 537 applicable). We use recursiveness to avoid module record duplicates. 538 */ 539 static void qt_excWriteModulesOnStack (WMOS_STATE *pState) 540 { 541 USHORT hmteThis = 0; 542 543 { 544 APIRET arc = NO_ERROR; 545 char szMod [CCHMAXPATH] = ""; 546 ULONG ulObject = 0, ulOffset = 0; 547 548 arc = DosQueryModFromEIP ((HMODULE *) &hmteThis, &ulObject, 549 sizeof (szMod), szMod, &ulOffset, 550 pState->ulRegEip); 551 if (arc == NO_ERROR && hmteThis != pState->hmteExe) 552 { 553 /* look if we've already seen this module using the hmteThis chain 554 * on the stack */ 555 USHORT *pH = &hmteThis; 556 /* calculate distance between recursive hmteThis on the stack */ 557 ULONG ulOuter = (ULONG) pState->pHmteOuter - (ULONG) pH; 558 ULONG cL = pState->cLevel; 559 while (cL != 0) 560 { 561 pH = (USHORT *)(((ULONG) pH) + ulOuter); 562 if (*pH == hmteThis) 563 break; 564 -- cL; 565 } 566 if (cL == 0) 567 { 568 /* got an unique module handle */ 569 DosQueryModuleName (hmteThis, sizeof (szMod), szMod); 570 qt_excWriteModule (pState->file, hmteThis, szMod); 571 } 572 } 573 } 574 575 /* we do EBP validity check here as well as before the recursive call below 576 * to get a chance to translate EIP passed on the first call (as taken 577 * from the CONTEXTRECORD even if EBP there is invalid. */ 578 if (pState->ulRegEbp != 0 && pState->ulRegEbp < pState->ulStackLimit) 579 { 580 if ((pState->ulRegEbp & 0x00000FFF) == 0x00000000) 581 { 582 /* we're on a page boundary: check access */ 583 while (pState->ulRegEbp < pState->ulStackLimit) 584 { 585 ULONG ulCount = 0x1000; 586 ULONG ulFlags = 0; 587 APIRET arc = DosQueryMem ((void *) pState->ulRegEbp, 588 &ulCount, &ulFlags); 589 if ( (arc != NO_ERROR) 590 || ( arc == NO_ERROR 591 && (ulFlags & (PAG_COMMIT|PAG_READ)) 592 != (PAG_COMMIT|PAG_READ))) 593 { 594 /* try go to the next page */ 595 /// @todo (r=dmik) I'm not sure how much it is correct, 596 // I've just taken the logic from xwphelpers sources. 597 pState->ulRegEbp += 0x1000; 598 continue; /* while */ 599 } 600 break; 601 } 602 } 603 604 /* get the return address to the previous call */ 605 pState->ulRegEip = *(((PULONG) pState->ulRegEbp) + 1); 606 /* get the address of the outer stack frame */ 607 pState->ulRegEbp = *((PULONG) pState->ulRegEbp); 608 609 if (pState->ulRegEbp != 0 && pState->ulRegEbp < pState->ulStackLimit) 610 { 611 pState->cLevel ++; 612 pState->pHmteOuter = &hmteThis; 613 qt_excWriteModulesOnStack (pState); 614 } 615 } 476 616 } 477 617 … … 479 619 Writes exception information to the log file. 480 620 */ 481 static void qt_excWriteException( FILE *file, 482 const char *pszExeName, 483 const char *pszExeBase, 484 PPIB ppib, PTIB ptib, 621 static void qt_excWriteException (FILE *file, 622 PROCESSINFO *pInfo, 485 623 PEXCEPTIONREPORTRECORD pReportRec, 486 PCONTEXTRECORD pContextRec ) 487 { 488 ULONG aulBuf[3]; 489 490 // *** application info 491 492 { 493 fprintf( file, " <Application name=\"" ); 494 if ( XcptPvt::askCallback( QtOS2SysXcptReq_AppName ) == TRUE ) 495 XcptPvt::letCallback( QtOS2SysXcptReq_AppName ); 624 PCONTEXTRECORD pContextRec) 625 { 626 ULONG ul = 0; 627 ULONG aulBuf [3]; 628 629 /* *** application info */ 630 631 { 632 fprintf (file, " <Application name=\""); 633 if (XcptPvt::askCallback (QtOS2SysXcptReq_AppName) == TRUE) 634 XcptPvt::letCallback (QtOS2SysXcptReq_AppName); 496 635 else 497 qt_excEscapeString ( file, pszExeBase);498 fprintf ( file, "\" version=\"");499 if ( XcptPvt::askCallback( QtOS2SysXcptReq_AppVer ) == TRUE)500 XcptPvt::letCallback ( QtOS2SysXcptReq_AppVer);636 qt_excEscapeString (file, pInfo->pszBaseName); 637 fprintf (file, "\" version=\""); 638 if (XcptPvt::askCallback (QtOS2SysXcptReq_AppVer) == TRUE) 639 XcptPvt::letCallback (QtOS2SysXcptReq_AppVer); 501 640 else 502 fprintf ( file, "unknown");503 fprintf ( file, "\">\n");504 505 if ( XcptPvt::askCallback( QtOS2SysXcptReq_ReportTo ) == TRUE)506 { 507 fprintf ( file, " <Report to=\"");508 XcptPvt::letCallback ( QtOS2SysXcptReq_ReportTo);509 if ( XcptPvt::askCallback( QtOS2SysXcptReq_ReportSubj ) == TRUE)510 { 511 fprintf ( file, "\" subject=\"");512 XcptPvt::letCallback ( QtOS2SysXcptReq_ReportSubj);513 } 514 fprintf ( file, "\"/>\n");641 fprintf (file, "unknown"); 642 fprintf (file, "\">\n"); 643 644 if (XcptPvt::askCallback (QtOS2SysXcptReq_ReportTo) == TRUE) 645 { 646 fprintf (file, " <Report to=\""); 647 XcptPvt::letCallback (QtOS2SysXcptReq_ReportTo); 648 if (XcptPvt::askCallback (QtOS2SysXcptReq_ReportSubj) == TRUE) 649 { 650 fprintf (file, "\" subject=\""); 651 XcptPvt::letCallback (QtOS2SysXcptReq_ReportSubj); 652 } 653 fprintf (file, "\"/>\n"); 515 654 } 516 655 517 fprintf( file, " </Application>\n" ); 518 } 519 520 // *** system info 521 522 DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_REVISION, 523 &aulBuf, sizeof(aulBuf) ); 524 // Warp 3 is reported as 20.30 525 // Warp 4 is reported as 20.40 526 // Aurora is reported as 20.45 527 528 fprintf( file, 656 fprintf (file, " </Application>\n"); 657 } 658 659 /* *** generic exception info */ 660 661 fprintf (file, 662 " <Exception type=\"%08lX\" flags=\"%08lX\" address=\"%08lX\">\n", 663 pReportRec->ExceptionNum, pReportRec->fHandlerFlags, 664 (ULONG) pReportRec->ExceptionAddress); 665 666 for (ul = 0; ul < pReportRec->cParameters; ++ul) 667 { 668 fprintf (file, " <Param value=\"%08lX\"/>\n", 669 pReportRec->ExceptionInfo [ul]); 670 } 671 672 fprintf (file, " </Exception>\n"); 673 674 /* *** system info */ 675 676 DosQuerySysInfo (QSV_VERSION_MAJOR, QSV_VERSION_REVISION, 677 &aulBuf, sizeof (aulBuf)); 678 /* Warp 3 is reported as 20.30 */ 679 /* Warp 4 is reported as 20.40 */ 680 /* Aurora is reported as 20.45 */ 681 682 fprintf (file, 529 683 " <System name=\"OS/2\" version=\"%u.%u.%u\"/>\n", 530 aulBuf[0], aulBuf[1], aulBuf[2] ); 531 532 // *** process info 533 534 if ( ppib ) 535 { 536 fprintf( file, 537 " <Process ID=\"%04lX\" parentID=\"%04lX\">\n" 538 " <Module ID=\"%04lX\" name=\"", 539 ppib->pib_ulpid, ppib->pib_ulppid, ppib->pib_hmte ); 540 qt_excEscapeString( file, pszExeName ); 541 fprintf( file, 542 "\"/>\n" 543 " </Process>\n" ); 684 aulBuf[0], aulBuf[1], aulBuf[2]); 685 686 /* *** process info */ 687 688 fprintf (file, " <Process ID=\"%04lX\" parentID=\"%04lX\">\n", 689 pInfo->ppib->pib_ulpid, pInfo->ppib->pib_ulppid); 690 691 fprintf (file, " <Modules>\n"); 692 if (pInfo->bHaveSysState) 693 { 694 /* write process module and it's imports */ 695 qt_excWriteModules (file, pInfo->ppib->pib_hmte, pInfo->pLibRec, 1); 696 /* write loaded modules and their imports */ 697 if (pInfo->pProcRec->cLib && pInfo->pProcRec->pLibRec) 698 { 699 for (ULONG i = 0; i < pInfo->pProcRec->cLib; ++ i) 700 qt_excWriteModules (file, pInfo->pProcRec->pLibRec [i], 701 pInfo->pLibRec, 3); 702 } 544 703 } 545 704 else 546 qt_excWriteErrorMsg( file, 1, "ppib is NULL" ); 547 548 fprintf( file, " <Threads>\n" ); 549 550 if ( ptib && ptib->tib_ptib2 ) 551 qt_excWriteThreadInfo( file, ptib, pReportRec, pContextRec ); 552 else if ( !ptib ) 553 qt_excWriteErrorMsg( file, 1, "ptib is NULL" ); 554 else 555 qt_excWriteErrorMsg( file, 1, "ptib->tib_ptib2 is NULL" ); 556 557 fprintf( file, " </Threads>\n" ); 705 { 706 qt_excWriteModule (file, pInfo->ppib->pib_hmte, pInfo->pszFullName, 1); 707 WMOS_STATE State = { file, pContextRec->ctx_RegEbp, 708 pContextRec->ctx_RegEip, 709 (ULONG) pInfo->ptib->tib_pstacklimit, 710 pInfo->ppib->pib_hmte, 711 0 /* cLevel */, NULL /* pHmteOuter */ }; 712 qt_excWriteModulesOnStack (&State); 713 } 714 fprintf (file, " </Modules>\n"); 715 716 fprintf (file, " <Threads>\n"); 717 718 /* first, the current thread */ 719 QSTREC *pThrdRec = pInfo->pProcRec->pThrdRec; 720 if (pThrdRec) 721 { 722 /* locate the current thread structure */ 723 for (ul = 0; ul < pInfo->pProcRec->cTCB; ++ ul, ++ pThrdRec) 724 if ((ULONG) pThrdRec->tid == pInfo->ptib->tib_ptib2->tib2_ultid) 725 break; 726 if (ul == pInfo->pProcRec->cTCB) 727 pThrdRec = NULL; 728 } 729 qt_excWriteThreadInfo (file, pInfo->ptib, pThrdRec, pContextRec); 730 731 fprintf (file, " </Threads>\n"); 732 733 fprintf (file, " </Process>\n"); 558 734 } 559 735 … … 678 854 PVOID pv ) 679 855 { 680 PTIB ptib = NULL; 681 PPIB ppib = NULL; 682 856 PROCESSINFO Info = {0}; 857 683 858 /* From the VAC++3 docs: 684 859 * "The first thing an exception handler should do is check the … … 696 871 */ 697 872 698 if ( 699 (EH_EXIT_UNWIND | EH_UNWINDING | EH_NESTED_CALL))873 if (pReportRec->fHandlerFlags & 874 (EH_EXIT_UNWIND | EH_UNWINDING | EH_NESTED_CALL)) 700 875 return XCPT_CONTINUE_SEARCH; 701 876 702 / / can it ever fail?...703 DosGetInfoBlocks ( &ptib, &ppib);704 877 /* setup the process info structure */ 878 DosGetInfoBlocks (&Info.ptib, &Info.ppib); 879 705 880 switch (pReportRec->ExceptionNum) 706 881 { … … 712 887 case XCPT_INTEGER_OVERFLOW: 713 888 { 714 // "real" exceptions: 715 889 /* "real" exceptions: */ 890 891 APIRET arc = NO_ERROR; 892 PVOID pBuf = NULL; 893 894 char szFullExeName [CCHMAXPATH] = ""; 895 char szBaseExeName [CCHMAXPATH] = ""; 896 897 TIB2 Tib2Orig; 716 898 DATETIME dt; 717 char szFileName[CCHMAXPATH]; 899 900 char szFileName [CCHMAXPATH]; 718 901 FILE *file = NULL; 719 char szExeName[CCHMAXPATH] = "unknown"; 720 char szExeBase[CCHMAXPATH]; 721 722 DosBeep( 880, 200 ); 723 724 if ( ppib ) 725 { 726 // get the main module name 727 DosQueryModuleName( ppib->pib_hmte, sizeof(szExeName), 728 szExeName ); 729 730 // find the base name (w/o path and extension) 731 char *psz = strrchr( szExeName, '\\' ); 902 903 /* raise this thread's priority to do it fast */ 904 Tib2Orig = *Info.ptib->tib_ptib2; 905 Info.ptib->tib_ptib2 = &Tib2Orig; 906 DosSetPriority (PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0); 907 908 DosBeep (880, 200); 909 910 /* query system state */ 911 { 912 ULONG ulCB = 64 * 1024; 913 ULONG cTries = 3; 914 while (-- cTries) 915 { 916 arc = DosAllocMem (&pBuf, ulCB, PAG_WRITE | PAG_COMMIT); 917 if (arc == NO_ERROR) 918 { 919 memset (pBuf, 0, ulCB); 920 arc = DosQuerySysState (QS_PROCESS | QS_MTE, 0, 921 Info.ppib->pib_ulpid, 0, 922 pBuf, ulCB); 923 if (arc == NO_ERROR) 924 { 925 QSPTRREC *pPtrRec = (QSPTRREC *) pBuf; 926 Info.bHaveSysState = TRUE; 927 Info.pProcRec = pPtrRec->pProcRec; 928 Info.pLibRec = pPtrRec->pLibRec; 929 } 930 else if (arc == ERROR_BUFFER_OVERFLOW) 931 { 932 /* retry with some bigger buffer size */ 933 DosFreeMem (pBuf); 934 pBuf = NULL; 935 ulCB *= 2; 936 continue; 937 } 938 } 939 break; 940 } 941 } 942 943 /* get the main module name */ 944 DosQueryModuleName (Info.ppib->pib_hmte, 945 sizeof (szFullExeName), szFullExeName); 946 { 947 /* find the base name (w/o path and extension) */ 948 char *psz = strrchr (szFullExeName, '\\'); 732 949 if ( psz ) 733 950 ++ psz; 734 951 if ( !psz ) 735 psz = sz ExeName;736 strcpy ( szExeBase, psz);737 psz = strrchr ( szExeBase, '.');738 if ( psz)952 psz = szFullExeName; 953 strcpy (szBaseExeName, psz); 954 psz = strrchr (szBaseExeName, '.'); 955 if (psz) 739 956 *psz = '\0'; 740 } 741 742 // compose the desired base file name for the log file 743 // (<datetime>-<exe>) 744 DosGetDateTime( &dt ); 745 sprintf( szFileName, "%04d%02d%02d%02d%02d%02d-%s", 957 Info.pszFullName = szFullExeName; 958 Info.pszBaseName = szBaseExeName; 959 } 960 961 /* compose the desired base file name for the log file 962 * (<datetime>-<exe>) */ 963 DosGetDateTime (&dt); 964 sprintf (szFileName, "%04d%02d%02d%02d%02d%02d-%s", 746 965 dt.year, dt.month, dt.day, 747 966 dt.hours, dt.minutes, dt.seconds, 748 sz ExeBase);967 szBaseExeName); 749 968 750 / / open the log file:969 /* open the log file: */ 751 970 752 / / firsttry the home directory, then the root drive753 // (see QDir::homeDirPath())754 file = qt_excOpenLogFile ( getenv( "HOME" ), szFileName);755 if ( file == NULL)756 { 757 char *pszHomeDrive = getenv ( "HOMEDRIVE");758 char *pszHomePath = getenv ( "HOMEPATH");759 if ( 760 strlen( pszHomeDrive ) + strlen( pszHomePath ) < CCHMAXPATH)971 /* first, try the home directory, then the root drive 972 * (see QDir::homeDirPath()) */ 973 file = qt_excOpenLogFile (getenv ("HOME"), szFileName); 974 if (file == NULL) 975 { 976 char *pszHomeDrive = getenv ("HOMEDRIVE"); 977 char *pszHomePath = getenv ("HOMEPATH"); 978 if (pszHomeDrive && pszHomePath && 979 strlen (pszHomeDrive) + strlen (pszHomePath) < CCHMAXPATH) 761 980 { 762 char szHomePath [CCHMAXPATH];763 strcpy ( szHomePath, pszHomeDrive);764 strcat ( szHomePath, pszHomePath);765 file = qt_excOpenLogFile ( szHomePath, szFileName);981 char szHomePath [CCHMAXPATH]; 982 strcpy (szHomePath, pszHomeDrive); 983 strcat (szHomePath, pszHomePath); 984 file = qt_excOpenLogFile (szHomePath, szFileName); 766 985 } 767 986 } 768 if ( file == NULL ) 769 { 770 static char szBootDrive[] = "\0:"; 771 if ( !szBootDrive[0] ) 772 { 773 ULONG ulBootDrive; 774 DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, 775 &ulBootDrive, sizeof(ulBootDrive) ); 776 szBootDrive[0] = (char) ulBootDrive + 'A' - 1; 777 } 778 file = qt_excOpenLogFile( szBootDrive, szFileName ); 779 } 780 781 if ( file != NULL ) 782 { 783 fprintf( file, 784 "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" 785 "<!--\n" 786 " A fatal error has occured while running this application.\n" 787 " Please contact the application vendor, describe what happened\n" 788 " and send the contents of this file saved locally as\n" 789 " '%s'.\n" 790 "-->\n", 791 szFileName ); 792 793 fprintf( file, 987 if (file == NULL) 988 { 989 char szBootDrive[] = "\0:"; 990 ULONG ulBootDrive; 991 DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, 992 &ulBootDrive, sizeof(ulBootDrive) ); 993 szBootDrive[0] = (char) ulBootDrive + 'A' - 1; 994 file = qt_excOpenLogFile (szBootDrive, szFileName); 995 } 996 997 if (file != NULL) 998 { 999 fprintf (file, 1000 "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" 1001 "<!--\n" 1002 " A fatal error has occured while running this application.\n" 1003 " Please contact the application vendor, describe what happened\n" 1004 " and send the contents of this file saved locally as\n" 1005 " '%s'.\n" 1006 "-->\n", 1007 szFileName); 1008 1009 fprintf (file, 794 1010 "<Trap timestamp=\"%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d\" " 795 1011 "version=\"1.0\"\n" … … 799 1015 dt.hours, dt.minutes, dt.seconds, 800 1016 (dt.timezone > 0 ? '-' : '+'), 801 abs ( dt.timezone / 60),802 abs ( dt.timezone % 60),1017 abs (dt.timezone / 60), 1018 abs (dt.timezone % 60), 803 1019 QT_VERSION_STR ); 804 1020 805 1021 XcptPvt::file = file; 806 1022 807 // write trap information 808 qt_excWriteException( file, szExeName, szExeBase, 809 ppib, ptib, pReportRec, pContextRec ); 1023 /* write trap information */ 1024 qt_excWriteException (file, &Info, pReportRec, pContextRec); 810 1025 811 1026 XcptPvt::file = NULL; 812 1027 813 fprintf ( file, "</Trap>\n\n");814 fclose ( file);1028 fprintf (file, "</Trap>\n\n"); 1029 fclose (file); 815 1030 816 / / attempt to display the created file1031 /* attempt to display the created file */ 817 1032 { 818 1033 STARTDATA SData = {0}; … … 820 1035 ULONG ulSessID = 0; 821 1036 822 SData.Length = sizeof (STARTDATA);1037 SData.Length = sizeof (STARTDATA); 823 1038 SData.PgmName = "E.EXE"; 824 1039 SData.PgmInputs = szFileName; 825 1040 826 DosStartSession ( &SData, &ulSessID, &pid);1041 DosStartSession (&SData, &ulSessID, &pid); 827 1042 } 828 1043 } 829 1044 else 830 DosBeep( 220, 200 ); 1045 DosBeep (220, 200); 1046 1047 if (pBuf != NULL) 1048 DosFreeMem (pBuf); 1049 1050 /* reset old priority */ 1051 DosSetPriority (PRTYS_THREAD, (Tib2Orig.tib2_ulpri & 0x0F00) >> 8, 1052 (UCHAR) Tib2Orig.tib2_ulpri, 1053 0); 831 1054 } 832 1055 break; 833 1056 } 834 1057 835 / / we never handle the exception ourselves836 837 if ( ptib && ptib->tib_ptib2 &&ptib->tib_ptib2->tib2_ultid == 1 &&838 QtOS2SysXcptMainHandler::libcHandler != NULL)839 { 840 / /we are on the main thread and were installed from qt_init() during841 //QApplication initialization using a hack; pass control back to the842 // LIBC exception handler843 return QtOS2SysXcptMainHandler::libcHandler (pReportRec, pRegRec,844 pContextRec, pv 1058 /* we never handle the exception ourselves */ 1059 1060 if (Info.ptib->tib_ptib2->tib2_ultid == 1 && 1061 QtOS2SysXcptMainHandler::libcHandler != NULL) 1062 { 1063 /* we are on the main thread and were installed from qt_init() during 1064 * QApplication initialization using a hack; pass control back to the 1065 * LIBC exception handler */ 1066 return QtOS2SysXcptMainHandler::libcHandler (pReportRec, pRegRec, 1067 pContextRec, pv); 845 1068 } 846 1069
Note:
See TracChangeset
for help on using the changeset viewer.