|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: debug.c ! 3: * ! 4: * debug helper routines ! 5: * ! 6: * Copyright (c) 1992-1993 Microsoft Corporation ! 7: * ! 8: \**************************************************************************/ ! 9: ! 10: #include <stdio.h> ! 11: #include <stdarg.h> ! 12: #include <stdlib.h> ! 13: ! 14: #include "driver.h" ! 15: ! 16: #include <ntsdexts.h> ! 17: ! 18: #include "lines.h" ! 19: ! 20: ! 21: #if DBG ! 22: ! 23: #define LOG_SIZE_IN_BYTES 4000 ! 24: ! 25: typedef struct _LOGGER { ! 26: ULONG ulEnd; ! 27: ULONG ulCurrent; ! 28: CHAR achBuf[LOG_SIZE_IN_BYTES]; ! 29: } DBGLOG; ! 30: ! 31: #define GetAddress(dst, src)\ ! 32: try {\ ! 33: dst = (VOID*) lpGetExpressionRoutine(src);\ ! 34: } except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?\ ! 35: EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {\ ! 36: lpOutputRoutine("NTSD: Access violation on \"%s\", switch to server context\n", src);\ ! 37: return;\ ! 38: } ! 39: ! 40: DBGLOG glog = {0, 0}; // If you muck with this, fix 'dumplog' too ! 41: ULONG DebugLevel = 0; ! 42: ULONG LogLevel = 1; ! 43: ! 44: #endif // DBG ! 45: ! 46: /***************************************************************************** ! 47: * ! 48: * Routine Description: ! 49: * ! 50: * This function is variable-argument, level-sensitive debug print ! 51: * routine. ! 52: * If the specified debug level for the print statement is lower or equal ! 53: * to the current debug level, the message will be printed. ! 54: * ! 55: * Arguments: ! 56: * ! 57: * DebugPrintLevel - Specifies at which debugging level the string should ! 58: * be printed ! 59: * ! 60: * DebugMessage - Variable argument ascii c string ! 61: * ! 62: * Return Value: ! 63: * ! 64: * None. ! 65: * ! 66: ***************************************************************************/ ! 67: ! 68: VOID ! 69: DebugPrint( ! 70: ULONG DebugPrintLevel, ! 71: PCHAR DebugMessage, ! 72: ... ! 73: ) ! 74: ! 75: ! 76: { ! 77: ! 78: #if DBG ! 79: ! 80: va_list ap; ! 81: ! 82: va_start(ap, DebugMessage); ! 83: ! 84: if (DebugPrintLevel <= DebugLevel) { ! 85: ! 86: char buffer[128]; ! 87: ! 88: vsprintf(buffer, DebugMessage, ap); ! 89: ! 90: OutputDebugStringA(buffer); ! 91: } ! 92: ! 93: va_end(ap); ! 94: ! 95: #endif // DBG ! 96: ! 97: } // DebugPrint() ! 98: ! 99: ! 100: /***************************************************************************** ! 101: * ! 102: * Routine Description: ! 103: * ! 104: * This function is variable-argument, level-sensitive debug log ! 105: * routine. ! 106: * If the specified debug level for the log statement is lower or equal ! 107: * to the current debug level, the message will be logged. ! 108: * ! 109: * Arguments: ! 110: * ! 111: * DebugLogLevel - Specifies at which debugging level the string should ! 112: * be logged ! 113: * ! 114: * DebugMessage - Variable argument ascii c string ! 115: * ! 116: * Return Value: ! 117: * ! 118: * None. ! 119: * ! 120: ***************************************************************************/ ! 121: ! 122: VOID ! 123: DebugLog( ! 124: ULONG DebugLogLevel, ! 125: PCHAR DebugMessage, ! 126: ... ! 127: ) ! 128: ! 129: ! 130: { ! 131: ! 132: #if DBG ! 133: ! 134: va_list ap; ! 135: ! 136: va_start(ap, DebugMessage); ! 137: ! 138: if (DebugLogLevel <= LogLevel) { ! 139: ! 140: char buffer[128]; ! 141: int length; ! 142: ! 143: length = vsprintf(buffer, DebugMessage, ap); ! 144: ! 145: length++; // Don't forget '\0' terminator! ! 146: ! 147: // Wrap around to the beginning of the log if not enough room for ! 148: // string: ! 149: ! 150: if (glog.ulCurrent + length >= LOG_SIZE_IN_BYTES) { ! 151: glog.ulEnd = glog.ulCurrent; ! 152: glog.ulCurrent = 0; ! 153: } ! 154: ! 155: memcpy(&glog.achBuf[glog.ulCurrent], buffer, length); ! 156: glog.ulCurrent += length; ! 157: } ! 158: ! 159: va_end(ap); ! 160: ! 161: #endif // DBG ! 162: ! 163: } // DebugLog() ! 164: ! 165: ! 166: /***************************************************************************** ! 167: * ! 168: * Routine Description: ! 169: * ! 170: * This function is called as an NTSD extension to dump a LineState ! 171: * ! 172: * Arguments: ! 173: * ! 174: * hCurrentProcess - Supplies a handle to the current process (at the ! 175: * time the extension was called). ! 176: * ! 177: * hCurrentThread - Supplies a handle to the current thread (at the ! 178: * time the extension was called). ! 179: * ! 180: * CurrentPc - Supplies the current pc at the time the extension is ! 181: * called. ! 182: * ! 183: * lpExtensionApis - Supplies the address of the functions callable ! 184: * by this extension. ! 185: * ! 186: * lpArgumentString - the float to display ! 187: * ! 188: * Return Value: ! 189: * ! 190: * None. ! 191: * ! 192: ***************************************************************************/ ! 193: VOID dumplog( ! 194: HANDLE hCurrentProcess, ! 195: HANDLE hCurrentThread, ! 196: DWORD dwCurrentPc, ! 197: PNTSD_EXTENSION_APIS lpExtensionApis, ! 198: LPSTR lpArgumentString) ! 199: { ! 200: ! 201: #if DBG ! 202: ! 203: PNTSD_OUTPUT_ROUTINE lpOutputRoutine; ! 204: PNTSD_GET_EXPRESSION lpGetExpressionRoutine; ! 205: PNTSD_GET_SYMBOL lpGetSymbolRoutine; ! 206: ! 207: ULONG cFrom; ! 208: ULONG cTo; ! 209: ULONG cCurrent; ! 210: DBGLOG* plogOriginal; ! 211: DBGLOG* plog; ! 212: ULONG ulCurrent; ! 213: ULONG ulEnd; ! 214: CHAR* pchEnd; ! 215: CHAR* pch; ! 216: ! 217: UNREFERENCED_PARAMETER(hCurrentThread); ! 218: UNREFERENCED_PARAMETER(dwCurrentPc); ! 219: ! 220: lpOutputRoutine = lpExtensionApis->lpOutputRoutine; ! 221: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine; ! 222: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine; ! 223: ! 224: lpOutputRoutine("!s3.dumplog [<from#> [<to#>]]\n\n"); ! 225: ! 226: // Evaluate the argument string to get the address of ! 227: // the Line Structure ! 228: ! 229: cTo = 1; // Defaults ! 230: cFrom = 20; ! 231: ! 232: pch = strpbrk(lpArgumentString, "0123456789"); ! 233: if (pch != NULL) // Use defaults if no args given ! 234: { ! 235: cFrom = atoi(pch); ! 236: pch = strchr(pch, ' '); ! 237: if (pch != NULL) ! 238: { ! 239: pch = strpbrk(pch, "0123456789"); ! 240: if (pch != NULL) ! 241: cTo = atoi(pch); ! 242: } ! 243: } ! 244: ! 245: // Do some parameter validation, then read the log into the ! 246: // debugger process's address space: ! 247: ! 248: if (cTo >= cFrom) ! 249: cTo = cFrom; ! 250: ! 251: if (cTo < 1) ! 252: { ! 253: cTo = 1; ! 254: cFrom = 1; ! 255: } ! 256: ! 257: GetAddress(plogOriginal, "glog"); ! 258: ! 259: if (!ReadProcessMemory(hCurrentProcess, ! 260: (LPVOID) &(plogOriginal->ulCurrent), ! 261: &ulCurrent, ! 262: sizeof(ulCurrent), ! 263: NULL)) ! 264: return; ! 265: ! 266: if (!ReadProcessMemory(hCurrentProcess, ! 267: (LPVOID) &(plogOriginal->ulEnd), ! 268: &ulEnd, ! 269: sizeof(ulEnd), ! 270: NULL)) ! 271: return; ! 272: ! 273: if (ulCurrent == 0 && ulEnd == 0) ! 274: { ! 275: lpOutputRoutine("Log empty\n\n"); ! 276: return; ! 277: } ! 278: ! 279: plog = (DBGLOG*) LocalAlloc(0, sizeof(DBGLOG) + 1); ! 280: ! 281: if (plog == NULL) { ! 282: lpOutputRoutine("Couldn't allocate temporary buffer!\n"); ! 283: return; ! 284: } ! 285: ! 286: if (!ReadProcessMemory(hCurrentProcess, ! 287: (LPVOID) &(plogOriginal->achBuf[0]), ! 288: &plog->achBuf[1], ! 289: LOG_SIZE_IN_BYTES, ! 290: NULL)) ! 291: return; ! 292: ! 293: // Mark the first byte in the buffer as being a zero, because ! 294: // we're going to search backwards through the buffer for zeroes, ! 295: // and we'll want to stop when we get to the beginning: ! 296: ! 297: plog->achBuf[0] = 0; ! 298: ulCurrent++; ! 299: ulEnd++; ! 300: ! 301: // Find the start string by going backwards through the buffer ! 302: // and counting strings until the count becomes equal to 'cFrom': ! 303: ! 304: cCurrent = 0; ! 305: pch = &plog->achBuf[ulCurrent - 1]; ! 306: pchEnd = &plog->achBuf[0]; ! 307: ! 308: while (TRUE) ! 309: { ! 310: if (*(--pch) == 0) ! 311: { ! 312: cCurrent++; ! 313: if (--cFrom == 0) ! 314: break; ! 315: ! 316: if (pch == &plog->achBuf[ulCurrent - 1]) ! 317: break; // We're back to where we started! ! 318: } ! 319: ! 320: // Make sure we wrap the end of the buffer: ! 321: ! 322: if (pch <= pchEnd) ! 323: { ! 324: if (ulCurrent >= ulEnd) ! 325: break; ! 326: ! 327: pch = &plog->achBuf[ulEnd - 1]; ! 328: } ! 329: } ! 330: ! 331: // pch is pointing to zero byte before our start string: ! 332: ! 333: pch++; ! 334: ! 335: // Output the strings: ! 336: ! 337: pchEnd = &plog->achBuf[max(ulEnd, ulCurrent)]; ! 338: ! 339: while (cCurrent >= cTo) ! 340: { ! 341: lpOutputRoutine("-%li: %s", cCurrent, pch); ! 342: pch += strlen(pch) + 1; ! 343: cCurrent--; ! 344: ! 345: // Make sure we wrap when we get to the end of the buffer: ! 346: ! 347: if (pch >= pchEnd) ! 348: pch = &plog->achBuf[1]; // First char in buffer is a NULL ! 349: } ! 350: ! 351: lpOutputRoutine("\n"); ! 352: LocalFree(plog); ! 353: ! 354: #endif // DBG ! 355: ! 356: return; ! 357: } ! 358: ! 359: /***************************************************************************** ! 360: * ! 361: * Routine Description: ! 362: * ! 363: * This function is called as an NTSD extension to dump ! 364: * the CRTC registers of an S3 chip ! 365: * ! 366: * Arguments: ! 367: * ! 368: * hCurrentProcess - Supplies a handle to the current process (at the ! 369: * time the extension was called). ! 370: * ! 371: * hCurrentThread - Supplies a handle to the current thread (at the ! 372: * time the extension was called). ! 373: * ! 374: * CurrentPc - Supplies the current pc at the time the extension is ! 375: * called. ! 376: * ! 377: * lpExtensionApis - Supplies the address of the functions callable ! 378: * by this extension. ! 379: * ! 380: * lpArgumentString - the float to display ! 381: * ! 382: * Return Value: ! 383: * ! 384: * None. ! 385: * ! 386: ***************************************************************************/ ! 387: VOID dcrtc( ! 388: HANDLE hCurrentProcess, ! 389: HANDLE hCurrentThread, ! 390: DWORD dwCurrentPc, ! 391: PNTSD_EXTENSION_APIS lpExtensionApis, ! 392: LPSTR lpArgumentString) ! 393: { ! 394: ! 395: #if DBG ! 396: ! 397: PNTSD_OUTPUT_ROUTINE lpOutputRoutine; ! 398: PNTSD_GET_EXPRESSION lpGetExpressionRoutine; ! 399: PNTSD_GET_SYMBOL lpGetSymbolRoutine; ! 400: CHAR Symbol[64]; ! 401: DWORD Displacement; ! 402: BOOL b; ! 403: ! 404: BYTE szBuff[256]; ! 405: INT i; ! 406: BYTE ajCrtc[0x65]; ! 407: DWORD dwAddr; ! 408: ! 409: UNREFERENCED_PARAMETER(hCurrentThread); ! 410: UNREFERENCED_PARAMETER(dwCurrentPc); ! 411: ! 412: lpOutputRoutine = lpExtensionApis->lpOutputRoutine; ! 413: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine; ! 414: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine; ! 415: ! 416: // ! 417: // Evaluate the argument string to get the address of ! 418: // the Line Structure ! 419: // ! 420: ! 421: dwAddr = (lpGetExpressionRoutine)(lpArgumentString); ! 422: if (!dwAddr) { ! 423: return; ! 424: } ! 425: ! 426: // ! 427: // Get the symbolic name ! 428: // ! 429: ! 430: (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement); ! 431: ! 432: // ! 433: // Read from the debuggees address space into our own. ! 434: // ! 435: ! 436: b = ReadProcessMemory(hCurrentProcess, ! 437: (LPVOID)dwAddr, ! 438: ajCrtc, ! 439: sizeof(ajCrtc), ! 440: NULL); ! 441: ! 442: if (!b) { ! 443: return; ! 444: } ! 445: ! 446: for (i = 0; i < 0x65; i++) ! 447: { ! 448: sprintf(szBuff, "%4.4x: %2.2x\n", i, ajCrtc[i]); ! 449: (lpOutputRoutine)(szBuff); ! 450: } ! 451: ! 452: ! 453: #endif // DBG ! 454: ! 455: return; ! 456: } ! 457: ! 458: ! 459: ! 460: ! 461: ! 462: /***************************************************************************** ! 463: * ! 464: * Routine Description: ! 465: * ! 466: * This function is called as an NTSD extension to dump a LineState ! 467: * ! 468: * Arguments: ! 469: * ! 470: * hCurrentProcess - Supplies a handle to the current process (at the ! 471: * time the extension was called). ! 472: * ! 473: * hCurrentThread - Supplies a handle to the current thread (at the ! 474: * time the extension was called). ! 475: * ! 476: * CurrentPc - Supplies the current pc at the time the extension is ! 477: * called. ! 478: * ! 479: * lpExtensionApis - Supplies the address of the functions callable ! 480: * by this extension. ! 481: * ! 482: * lpArgumentString - the float to display ! 483: * ! 484: * Return Value: ! 485: * ! 486: * None. ! 487: * ! 488: ***************************************************************************/ ! 489: VOID dls( ! 490: HANDLE hCurrentProcess, ! 491: HANDLE hCurrentThread, ! 492: DWORD dwCurrentPc, ! 493: PNTSD_EXTENSION_APIS lpExtensionApis, ! 494: LPSTR lpArgumentString) ! 495: { ! 496: ! 497: #if DBG ! 498: ! 499: PNTSD_OUTPUT_ROUTINE lpOutputRoutine; ! 500: PNTSD_GET_EXPRESSION lpGetExpressionRoutine; ! 501: PNTSD_GET_SYMBOL lpGetSymbolRoutine; ! 502: CHAR Symbol[64]; ! 503: DWORD Displacement; ! 504: BOOL b; ! 505: ! 506: DWORD dwAddr; ! 507: LINESTATE ls; ! 508: BYTE szBuff[256]; ! 509: ! 510: UNREFERENCED_PARAMETER(hCurrentThread); ! 511: UNREFERENCED_PARAMETER(dwCurrentPc); ! 512: ! 513: lpOutputRoutine = lpExtensionApis->lpOutputRoutine; ! 514: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine; ! 515: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine; ! 516: ! 517: // ! 518: // Evaluate the argument string to get the address of ! 519: // the Line Structure ! 520: // ! 521: ! 522: dwAddr = (lpGetExpressionRoutine)(lpArgumentString); ! 523: if (!dwAddr) { ! 524: return; ! 525: } ! 526: ! 527: // ! 528: // Get the symbolic name ! 529: // ! 530: ! 531: (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement); ! 532: ! 533: // ! 534: // Read from the debuggees address space into our own. ! 535: // ! 536: ! 537: b = ReadProcessMemory(hCurrentProcess, ! 538: (LPVOID)dwAddr, ! 539: &ls, ! 540: sizeof(ls), ! 541: NULL); ! 542: ! 543: if (!b) { ! 544: return; ! 545: } ! 546: ! 547: ! 548: sprintf(szBuff, "LineState: %8.8x\n", dwAddr); ! 549: (lpOutputRoutine)(szBuff); ! 550: ! 551: sprintf(szBuff, "\tjAnd : %2.2x\n", ls.jAnd); ! 552: (lpOutputRoutine)(szBuff); ! 553: ! 554: sprintf(szBuff, "\tjXor : %2.2x\n", ls.jXor); ! 555: (lpOutputRoutine)(szBuff); ! 556: ! 557: sprintf(szBuff, "\tpspStart : %4.4x\n", ls.pspStart); ! 558: (lpOutputRoutine)(szBuff); ! 559: ! 560: sprintf(szBuff, "\tpspEnd : %4.4x\n", ls.pspEnd); ! 561: (lpOutputRoutine)(szBuff); ! 562: ! 563: sprintf(szBuff, "\tpsp : %4.4x\n", ls.psp); ! 564: (lpOutputRoutine)(szBuff); ! 565: ! 566: sprintf(szBuff, "\tspRemaining : %4.4x\n", ls.spRemaining); ! 567: (lpOutputRoutine)(szBuff); ! 568: ! 569: sprintf(szBuff, "\tspTotal : %4.4x\n", ls.spTotal); ! 570: (lpOutputRoutine)(szBuff); ! 571: ! 572: sprintf(szBuff, "\tspTotal2 : %4.4x\n", ls.spTotal2); ! 573: (lpOutputRoutine)(szBuff); ! 574: ! 575: sprintf(szBuff, "\tspNext : %4.4x\n", ls.spNext); ! 576: (lpOutputRoutine)(szBuff); ! 577: ! 578: sprintf(szBuff, "\tspComplex : %4.4x\n", ls.spComplex); ! 579: (lpOutputRoutine)(szBuff); ! 580: ! 581: sprintf(szBuff, "\taspRtoL : %4.4x\n", ls.aspRtoL); ! 582: (lpOutputRoutine)(szBuff); ! 583: ! 584: sprintf(szBuff, "\taspLtoR : %4.4x\n", ls.aspLtoR); ! 585: (lpOutputRoutine)(szBuff); ! 586: ! 587: sprintf(szBuff, "\tulStyleMask : %4.4x\n", ls.ulStyleMask); ! 588: (lpOutputRoutine)(szBuff); ! 589: ! 590: sprintf(szBuff, "\txyDensity : %4.4x\n", ls.xyDensity); ! 591: (lpOutputRoutine)(szBuff); ! 592: ! 593: sprintf(szBuff, "\tcStyle : %4.4x\n", ls.cStyle); ! 594: (lpOutputRoutine)(szBuff); ! 595: ! 596: sprintf(szBuff, "\tulStyleMaskLtoR : %4.4x\n", ls.ulStyleMaskLtoR); ! 597: (lpOutputRoutine)(szBuff); ! 598: ! 599: sprintf(szBuff, "\tulStyleMaskRtoL : %4.4x\n", ls.ulStyleMaskRtoL); ! 600: (lpOutputRoutine)(szBuff); ! 601: ! 602: sprintf(szBuff, "\tulStartMask : %4.4x\n", ls.ulStartMask); ! 603: (lpOutputRoutine)(szBuff); ! 604: ! 605: #endif // DBG ! 606: ! 607: return; ! 608: } ! 609: ! 610: /***************************************************************************** ! 611: * ! 612: * Routine Description: ! 613: * ! 614: * This function is called as an NTSD extension to dump a dword ! 615: * (It's real function is as a prototype for other NT extensions.) ! 616: * ! 617: * Arguments: ! 618: * ! 619: * hCurrentProcess - Supplies a handle to the current process (at the ! 620: * time the extension was called). ! 621: * ! 622: * hCurrentThread - Supplies a handle to the current thread (at the ! 623: * time the extension was called). ! 624: * ! 625: * CurrentPc - Supplies the current pc at the time the extension is ! 626: * called. ! 627: * ! 628: * lpExtensionApis - Supplies the address of the functions callable ! 629: * by this extension. ! 630: * ! 631: * lpArgumentString - the float to display ! 632: * ! 633: * Return Value: ! 634: * ! 635: * None. ! 636: * ! 637: ***************************************************************************/ ! 638: VOID dd( ! 639: HANDLE hCurrentProcess, ! 640: HANDLE hCurrentThread, ! 641: DWORD dwCurrentPc, ! 642: PNTSD_EXTENSION_APIS lpExtensionApis, ! 643: LPSTR lpArgumentString) ! 644: { ! 645: ! 646: #if DBG ! 647: ! 648: PNTSD_OUTPUT_ROUTINE lpOutputRoutine; ! 649: PNTSD_GET_EXPRESSION lpGetExpressionRoutine; ! 650: PNTSD_GET_SYMBOL lpGetSymbolRoutine; ! 651: CHAR Symbol[64]; ! 652: DWORD Displacement; ! 653: BOOL b; ! 654: ! 655: DWORD dwAddr; ! 656: DWORD val; ! 657: BYTE szBuff[256]; ! 658: ! 659: UNREFERENCED_PARAMETER(hCurrentThread); ! 660: UNREFERENCED_PARAMETER(dwCurrentPc); ! 661: ! 662: lpOutputRoutine = lpExtensionApis->lpOutputRoutine; ! 663: lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine; ! 664: lpGetSymbolRoutine = lpExtensionApis->lpGetSymbolRoutine; ! 665: ! 666: // ! 667: // Evaluate the argument string to get the address of ! 668: // the Line Structure ! 669: // ! 670: ! 671: dwAddr = (lpGetExpressionRoutine)(lpArgumentString); ! 672: if (!dwAddr) { ! 673: return; ! 674: } ! 675: ! 676: // ! 677: // Get the symbolic name ! 678: // ! 679: ! 680: (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement); ! 681: ! 682: // ! 683: // Read from the debuggees address space into our own. ! 684: // ! 685: ! 686: b = ReadProcessMemory(hCurrentProcess, ! 687: (LPVOID)dwAddr, ! 688: &val, ! 689: sizeof(val), ! 690: NULL); ! 691: ! 692: if (!b) { ! 693: return; ! 694: } ! 695: ! 696: sprintf(szBuff, "%8.8x: %8.8x\n", dwAddr, val); ! 697: (lpOutputRoutine)(szBuff); ! 698: #endif // DBG ! 699: ! 700: return; ! 701: } ! 702:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.