Annotation of mstools/samples/deb/debdebug.c, revision 1.1.1.1

1.1       root        1: // ************************************************************************
                      2: // MODULE    : DEBDebug.c
                      3: // PURPOSE   : Debug support functions for the Debug Event Browser
                      4: // FUNCTIONS :
                      5: //   DbgEventThread()              - debug event processing thread
                      6: //   GetModuleFileNameFromHeader() - get the module name
                      7: //   SkipBreakPoint()              - skips over the break point in the debugee
                      8: // COMMENTS  :
                      9: // ************************************************************************
                     10: #include <Windows.H>
                     11: #include <String.H>          // strcpy(), strcat()
                     12: #include <StdIO.H>           // sprintf()
                     13: 
                     14: #include "LinkList.H"
                     15: #include "DEBMain.H"
                     16: #include "DEBMisc.H"
                     17: #include "DEBDebug.H"
                     18: 
                     19: 
                     20: // ************************************************************************
                     21: // FUNCTION : DebugEventThread( LPCTSTR  )
                     22: // PURPOSE  : Main debug event processing loop
                     23: // COMMENTS : A new debug event thread is created for each debugee process.
                     24: //            DebugeeFileName may be the process ID of and active process
                     25: //            or the name of a process to create.
                     26: //            Note: this build only supports browsing one process at a time.
                     27: // ************************************************************************
                     28: DWORD
                     29: DebugEventThread( LPCTSTR DebugeeFileName )
                     30: {
                     31:   static BOOL  fFirstTime = TRUE;
                     32:   static PNODE ThreadNode;          // used for inserting new thread nodes
                     33: 
                     34:   PNODE        TempNode;            // used for queries on thread linked list
                     35:   DEBUG_EVENT  DebugEvent;
                     36:   TCHAR        szDebugEventBuffer[256];
                     37:   TCHAR        szTempBuf[256];
                     38:   DWORD        NumberOfBytesRead;
                     39: 
                     40:   //-- temporary thread info node used for queries
                     41:   CreateNode( &ProcessList, &TempNode );
                     42: 
                     43:   //-- determine if 'attach to' or 'open' debugee
                     44:   //   DebugeeFileName may be dwProcessId and an actual filename
                     45:   if( !DebugActiveProcess( (DWORD) DebugeeFileName ) ) {
                     46: 
                     47:     //-- create the debugee process instead
                     48:     if( !CreateProcess(
                     49:            NULL,
                     50:            DebugeeFileName,
                     51:            (LPSECURITY_ATTRIBUTES) NULL,
                     52:            (LPSECURITY_ATTRIBUTES) NULL,
                     53:            TRUE,
                     54:            DebugMode | DebugeePriority | CREATE_NEW_CONSOLE,
                     55:            (LPVOID) NULL,
                     56:            (LPTSTR) NULL,
                     57:            &si, &pi ) ) {
                     58: 
                     59:       return( FALSE );
                     60: 
                     61:     }
                     62:     else {
                     63: 
                     64:       hProcess = pi.hProcess;
                     65:       CloseHandle( pi.hProcess );
                     66:       CloseHandle( pi.hThread );
                     67: 
                     68:     }
                     69:   }
                     70: 
                     71:   for(;;) {
                     72:     if( !WaitForDebugEvent( &DebugEvent, (DWORD) -1L ) ) {
                     73:       ListBoxPrintF( "%s", "Waiting..." );
                     74:       continue;
                     75:   }
                     76: 
                     77:     switch( DebugEvent.dwDebugEventCode ) {
                     78: 
                     79:       case EXCEPTION_DEBUG_EVENT:
                     80:         MakeDebugEventString( szDebugEventBuffer, "Exception:",
                     81:           &DebugEvent);
                     82: 
                     83:         switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
                     84: 
                     85:           case EXCEPTION_ACCESS_VIOLATION:
                     86:             strcat(szDebugEventBuffer, "ACCESS_VIOLATION");
                     87:             break;
                     88: 
                     89:           case EXCEPTION_BREAKPOINT:
                     90:             strcat(szDebugEventBuffer, "BREAKPOINT");
                     91:             break;
                     92: 
                     93:           case EXCEPTION_DATATYPE_MISALIGNMENT:
                     94:             strcat(szDebugEventBuffer, "DATATYPE_MISALIGNMENT");
                     95:             break;
                     96: 
                     97:           case EXCEPTION_SINGLE_STEP:
                     98:             strcat(szDebugEventBuffer, "SINGLE_STEP");
                     99:             break;
                    100: 
                    101:           case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
                    102:             strcat(szDebugEventBuffer, "ARRAY_BOUNDS_EXCEEDED");
                    103:             break;
                    104: 
                    105:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:
                    106:             strcat(szDebugEventBuffer, "FLT_DIVIDE_BY_ZERO");
                    107:             break;
                    108: 
                    109:           case EXCEPTION_FLT_INVALID_OPERATION:
                    110:             strcat(szDebugEventBuffer, "FLT_INVALID_OPERATION");
                    111:             break;
                    112: 
                    113:           case EXCEPTION_FLT_OVERFLOW:
                    114:             strcat(szDebugEventBuffer, "FLT_OVERFLOW");
                    115:             break;
                    116: 
                    117:           case EXCEPTION_FLT_STACK_CHECK:
                    118:             strcat(szDebugEventBuffer, "FLT_STACK_CHECK");
                    119:             break;
                    120: 
                    121:           case EXCEPTION_FLT_UNDERFLOW:
                    122:             strcat(szDebugEventBuffer, "FLT_UNDERFLOW");
                    123:             break;
                    124: 
                    125:           case EXCEPTION_INT_DIVIDE_BY_ZERO:
                    126:             strcat(szDebugEventBuffer, "INT_DIVIDE_BY_ZERO");
                    127:             break;
                    128: 
                    129:           case EXCEPTION_INT_OVERFLOW:
                    130:             strcat(szDebugEventBuffer, "INT_OVERFLOW");
                    131:             break;
                    132: 
                    133:           case EXCEPTION_PRIV_INSTRUCTION:
                    134:             strcat(szDebugEventBuffer, "PRIV_INSTRUCTION");
                    135:             break;
                    136: 
                    137:           default:
                    138:             strcat(szDebugEventBuffer, "Unknown [0x");
                    139:             strcat(szDebugEventBuffer,
                    140:               LongToCharUpper( (LONG) DebugEvent.u.Exception.ExceptionRecord.ExceptionCode, szTempBuf, 16) );
                    141:             strcat(szDebugEventBuffer, "]");
                    142:             break;
                    143:         }
                    144:         if( fVerbose ) {
                    145:           strcat(szDebugEventBuffer, " - dwFirstChance:");
                    146:           strcat(szDebugEventBuffer,
                    147:             LongToCharUpper( (LONG) DebugEvent.u.Exception.dwFirstChance, szTempBuf, 10) );
                    148:         }
                    149:         else {
                    150:           if(DebugEvent.u.Exception.dwFirstChance != 0)
                    151:             strcat(szDebugEventBuffer, " - First Chance");
                    152:           else
                    153:             strcat(szDebugEventBuffer, " - Second Chance");
                    154:         }
                    155:         break;
                    156: 
                    157:       case CREATE_THREAD_DEBUG_EVENT:
                    158:         MakeDebugEventString(szDebugEventBuffer, "Create Thread",
                    159:           &DebugEvent);
                    160:         if( fVerbose ) {
                    161:           strcat(szDebugEventBuffer, " - hThread:0x");
                    162:           strcat(szDebugEventBuffer,
                    163:             LongToCharUpper( (LONG)  DebugEvent.u.CreateThread.hThread, szTempBuf, 16) );
                    164:           strcat(szDebugEventBuffer, " - lpStartAddress:0x");
                    165:           strcat(szDebugEventBuffer,
                    166:             LongToCharUpper( (LONG) DebugEvent.u.CreateThread.lpStartAddress, szTempBuf, 16) );
                    167:         }
                    168:         break;
                    169: 
                    170:       case CREATE_PROCESS_DEBUG_EVENT:
                    171:         MakeDebugEventString(szDebugEventBuffer, "Create Process",
                    172:           &DebugEvent);
                    173:         if( fVerbose ) {
                    174:           strcat(szDebugEventBuffer, " - hFile:0x");
                    175:           strcat(szDebugEventBuffer,
                    176:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hFile, szTempBuf, 16) );
                    177:           strcat(szDebugEventBuffer, " - hProcess:0x");
                    178:           strcat(szDebugEventBuffer,
                    179:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hProcess, szTempBuf, 16) );
                    180:           strcat(szDebugEventBuffer, " - hThread:0x");
                    181:           strcat(szDebugEventBuffer,
                    182:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hThread, szTempBuf, 16) );
                    183:           strcat(szDebugEventBuffer, " - lpBaseOfImage:0x");
                    184:           strcat(szDebugEventBuffer,
                    185:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpBaseOfImage, szTempBuf, 16) );
                    186:           strcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:");
                    187:           strcat(szDebugEventBuffer,
                    188:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.dwDebugInfoFileOffset, szTempBuf, 10) );
                    189:           strcat(szDebugEventBuffer, " - nDebugInfoSize:");
                    190:           strcat(szDebugEventBuffer,
                    191:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.nDebugInfoSize, szTempBuf, 10) );
                    192:           strcat(szDebugEventBuffer, " - lpStartAddress:0x");
                    193:           strcat(szDebugEventBuffer,
                    194:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpStartAddress, szTempBuf, 16) );
                    195:         }
                    196:         break;
                    197: 
                    198:       case EXIT_THREAD_DEBUG_EVENT:
                    199:         MakeDebugEventString(szDebugEventBuffer, "Exit Thread",
                    200:           &DebugEvent);
                    201: 
                    202:         if( fVerbose ) {
                    203:           strcat(szDebugEventBuffer, " - dwExitCode:");
                    204:         }
                    205:         else {
                    206:           strcat(szDebugEventBuffer, " - Returned:");
                    207:         }
                    208:         strcat(szDebugEventBuffer,
                    209:           LongToCharUpper( (LONG) DebugEvent.u.ExitThread.dwExitCode, szTempBuf, 10) );
                    210:         break;
                    211: 
                    212:       case EXIT_PROCESS_DEBUG_EVENT:
                    213:         MakeDebugEventString(szDebugEventBuffer, "Exit Process",
                    214:           &DebugEvent);
                    215:         if( fVerbose ) {
                    216:           strcat(szDebugEventBuffer, " - dwExitCode:");
                    217:         }
                    218:         else {
                    219:           strcat(szDebugEventBuffer, " - Returned:");
                    220:         }
                    221:         strcat(szDebugEventBuffer,
                    222:           LongToCharUpper( (LONG) DebugEvent.u.ExitProcess.dwExitCode, szTempBuf, 10) );
                    223:         break;
                    224: 
                    225:       case LOAD_DLL_DEBUG_EVENT:
                    226:         MakeDebugEventString(szDebugEventBuffer, "Load DLL:",
                    227:           &DebugEvent);
                    228: 
                    229:         GetModuleFileNameFromHeader(
                    230:           hProcess, DebugEvent.u.LoadDll.hFile,
                    231:           szTempBuf, 256 );
                    232:         strcat( szDebugEventBuffer, szTempBuf );
                    233:         if( fVerbose ) {
                    234:           strcat(szDebugEventBuffer, " - hFile:0x");
                    235:           strcat(szDebugEventBuffer,
                    236:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.hFile, szTempBuf, 16) );
                    237:           strcat(szDebugEventBuffer, " - lpBaseOfDll:0x");
                    238:           strcat(szDebugEventBuffer,
                    239:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.lpBaseOfDll, szTempBuf, 16) );
                    240:           strcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:");
                    241:           strcat(szDebugEventBuffer,
                    242:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.dwDebugInfoFileOffset, szTempBuf, 10) );
                    243:           strcat(szDebugEventBuffer, " - nDebugInfoSize:");
                    244:           strcat(szDebugEventBuffer,
                    245:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.nDebugInfoSize, szTempBuf, 10) );
                    246:         }
                    247:         break;
                    248: 
                    249:       case UNLOAD_DLL_DEBUG_EVENT:
                    250:         MakeDebugEventString(szDebugEventBuffer, "Unload DLL",
                    251:           &DebugEvent);
                    252:         if( fVerbose ) {
                    253:           strcat(szDebugEventBuffer, " - lpBaseOfDLL:0x");
                    254:           strcat(szDebugEventBuffer,
                    255:             LongToCharUpper( (LONG) DebugEvent.u.UnloadDll.lpBaseOfDll, szTempBuf, 16) );
                    256:         }
                    257:         break;
                    258: 
                    259:       case OUTPUT_DEBUG_STRING_EVENT:
                    260:         MakeDebugEventString(szDebugEventBuffer, "Output Debug String",
                    261:           &DebugEvent);
                    262:         strcat(szDebugEventBuffer, ":\"");
                    263: 
                    264:         //-- According to Win32 Specs Rev3, I need to use ReadVirtualMemory
                    265:         //   however this incorrect.  ReadProcessMemory is the correct API
                    266:         ReadProcessMemory( hProcess,
                    267:           DebugEvent.u.DebugString.lpDebugStringData,
                    268:           szTempBuf, DebugEvent.u.DebugString.nDebugStringLength,
                    269:           &NumberOfBytesRead );
                    270:         strcat(szDebugEventBuffer, szTempBuf );
                    271:         strcat(szDebugEventBuffer, "\"" );
                    272:         if( fVerbose ) {
                    273:           strcat(szDebugEventBuffer, " - fUnicode:");
                    274:           strcat(szDebugEventBuffer,
                    275:             LongToCharUpper( (LONG) DebugEvent.u.DebugString.fUnicode, szTempBuf, 10) );
                    276:           strcat(szDebugEventBuffer, " - nDebugStringLength:");
                    277:           strcat(szDebugEventBuffer,
                    278:             LongToCharUpper( (LONG) DebugEvent.u.DebugString.nDebugStringLength, szTempBuf, 10) );
                    279:         }
                    280:         break;
                    281: 
                    282:       default:
                    283:         MakeDebugEventString(szDebugEventBuffer, "Debug Event:",
                    284:           &DebugEvent);
                    285:         strcat(szDebugEventBuffer, "Unknown [0x");
                    286:         strcat(szDebugEventBuffer,
                    287:           LongToCharUpper( (LONG) DebugEvent.dwDebugEventCode, szTempBuf, 16) );
                    288:         strcat(szDebugEventBuffer, "]");
                    289:         break;
                    290:     }
                    291: 
                    292:     //-- insert the debug event string into the listbox
                    293:     ListBoxPrintF( "%s", szDebugEventBuffer );
                    294: 
                    295:     //-- handle minimal exception handling needs for particular events
                    296:     switch( DebugEvent.dwDebugEventCode ) {
                    297: 
                    298:       case EXCEPTION_DEBUG_EVENT:
                    299:         switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
                    300: 
                    301:          #if( MIPS == 1 )
                    302:           case STATUS_BREAKPOINT:
                    303:             //-- increment instruction pointer past the break point
                    304:             //   only needed for the MIPS R4000
                    305:             if( !SkipBreakPoint( DebugEvent.dwThreadId ) )
                    306:               ListBoxInsert( hWndDebugList, &MaxStrLen,
                    307:                 "--> Failed To skip over the Break Point" );
                    308:             break;
                    309:          #endif
                    310: 
                    311:           case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
                    312:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:
                    313:           case EXCEPTION_FLT_INVALID_OPERATION:
                    314:           case EXCEPTION_FLT_OVERFLOW:
                    315:           case EXCEPTION_FLT_STACK_CHECK:
                    316:           case EXCEPTION_FLT_UNDERFLOW:
                    317:           case EXCEPTION_INT_DIVIDE_BY_ZERO:
                    318:           case EXCEPTION_INT_OVERFLOW:
                    319:           case EXCEPTION_PRIV_INSTRUCTION:
                    320:           case STATUS_ACCESS_VIOLATION:
                    321:             ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId,
                    322:               DBG_EXCEPTION_NOT_HANDLED );
                    323:         }
                    324:         break;
                    325: 
                    326:       case CREATE_PROCESS_DEBUG_EVENT:
                    327:         CreateNode( &ProcessList, &ThreadNode );
                    328:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    329:         (ThreadNode->NodeData).hThread    = DebugEvent.u.CreateProcessInfo.hThread;
                    330:         InsertNode( &ProcessList, ThreadNode );
                    331:         if( ++ActiveProcesses == 1 ) {
                    332:           //-- store the current process handle in the temp global handle
                    333:           hProcess = DebugEvent.u.CreateProcessInfo.hProcess;
                    334:         }
                    335:         break;
                    336: 
                    337:       case CREATE_THREAD_DEBUG_EVENT:
                    338:         CreateNode( &ProcessList, &ThreadNode );
                    339:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    340:         (ThreadNode->NodeData).hThread    = DebugEvent.u.CreateThread.hThread;
                    341:         InsertNode( &ProcessList, ThreadNode );
                    342:         break;
                    343: 
                    344:       case EXIT_THREAD_DEBUG_EVENT:
                    345:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    346:         GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 );
                    347:         DeleteCurrentNode( &ProcessList );
                    348:         break;
                    349: 
                    350:       case EXIT_PROCESS_DEBUG_EVENT:
                    351:         //-- if the event was EXIT_PROCESS_DEBUG_EVENT and it was the
                    352:         //   original process opened/attached to then exit the
                    353:         //   debug event processing thread.  Also do some cleanup first.
                    354:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    355:         GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 );
                    356:         DeleteCurrentNode( &ProcessList );
                    357:         DestroyNode( TempNode );
                    358:         if( --ActiveProcesses == 0 ) {
                    359:           ExitThread( TRUE );
                    360:         }
                    361:         break;
                    362:     }
                    363: 
                    364:     //-- default action - just continue
                    365:     ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId,
                    366:       DBG_CONTINUE );
                    367:   }
                    368: 
                    369:   return( FALSE );
                    370: }
                    371: 
                    372: 
                    373: // ************************************************************************
                    374: // FUNCTION : GetModuleFileNameFromHeader( HANDLE, HANDLE, LPTSTR, DWORD )
                    375: // PURPOSE  : Retrieves the DLL module name for a given file handle of a
                    376: //            the module.  Reads the module name from the EXE header.
                    377: // COMMENTS : Retrieves only the module name and not the pathname
                    378: // ************************************************************************
                    379: DWORD APIENTRY
                    380: GetModuleFileNameFromHeader( HANDLE hProcess, HANDLE hFile, LPTSTR lpszPath,
                    381:   DWORD cbPath )
                    382: {
                    383:   #define IMAGE_DOS_SIGNATURE     0x5A4D      // MZ
                    384:   #define IMAGE_OS2_SIGNATURE     0x454E      // NE
                    385:   #define IMAGE_NT_SIGNATURE      0x00004550  // PE00
                    386: 
                    387:   #define IMAGE_SECOND_HEADER_OFFSET     (15 * sizeof(ULONG)) // relative to file beginning
                    388:   #define IMAGE_BASE_OFFSET              (13 * sizeof(DWORD)) // relative to PE header base
                    389:   #define IMAGE_EXPORT_TABLE_RVA_OFFSET  (30 * sizeof(DWORD)) // relative to PE header base
                    390:   #define IMAGE_NAME_RVA_OFFSET           (3 * sizeof(DWORD)) // relative to Exports/Imports table base
                    391: 
                    392:   WORD   DosSignature;
                    393:   DWORD  NtSignature;
                    394:   DWORD  NumberOfBytesRead;
                    395: 
                    396:   DWORD  PeHeader, ImageBase, ExportTableRVA, NameRVA;
                    397: 
                    398:   //-- verify that the handle is not NULL
                    399:   if( !hFile ) {
                    400:     strcpy( lpszPath, "hFile is NULL!" );
                    401:     return( 0 );
                    402:   }
                    403: 
                    404:   //-- verify that the handle is for a disk file
                    405:   if( GetFileType(hFile) != FILE_TYPE_DISK ) {
                    406:     strcpy( lpszPath, "Incorrect hFile Type!" );
                    407:     return( 0 );
                    408:   }
                    409: 
                    410:   //-- Extract the filename from the EXE header
                    411:   ReadFile( hFile, &DosSignature, sizeof(DosSignature), &NumberOfBytesRead,
                    412:     (LPOVERLAPPED) NULL);
                    413: 
                    414:   if( DosSignature == IMAGE_DOS_SIGNATURE ) {
                    415: 
                    416:     SetFilePointer( hFile, IMAGE_SECOND_HEADER_OFFSET, (LPLONG) NULL,
                    417:       FILE_BEGIN );
                    418:     ReadFile( hFile, &PeHeader, sizeof(PeHeader),
                    419:       &NumberOfBytesRead, (LPOVERLAPPED) NULL );
                    420: 
                    421:     SetFilePointer( hFile, PeHeader, (LPLONG) NULL,
                    422:       FILE_BEGIN );
                    423:     ReadFile( hFile, &NtSignature, sizeof(NtSignature),
                    424:       &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    425: 
                    426:     if( NtSignature == IMAGE_NT_SIGNATURE ) {
                    427: 
                    428:       SetFilePointer( hFile, PeHeader+IMAGE_BASE_OFFSET,
                    429:          (LPLONG) NULL, FILE_BEGIN );
                    430:       ReadFile( hFile, &ImageBase, sizeof(ImageBase),
                    431:         &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    432: 
                    433:       SetFilePointer( hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET,
                    434:          (LPLONG) NULL, FILE_BEGIN );
                    435:       ReadFile( hFile, &ExportTableRVA, sizeof(ExportTableRVA),
                    436:         &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    437: 
                    438:       //-- now read from the virtual address space in the process
                    439:       ReadProcessMemory( hProcess,
                    440:          (LPVOID) (ImageBase + ExportTableRVA + IMAGE_NAME_RVA_OFFSET),
                    441:          &NameRVA, sizeof(NameRVA), &NumberOfBytesRead );
                    442: 
                    443:       ReadProcessMemory( hProcess,
                    444:          (LPVOID) (ImageBase+NameRVA),
                    445:          lpszPath, cbPath, &NumberOfBytesRead );
                    446: 
                    447:       return( NumberOfBytesRead );
                    448:     }
                    449:     else
                    450:       sprintf( lpszPath, "NtSignature is 0x%x!", NtSignature );
                    451: 
                    452:   }
                    453:   else
                    454:     sprintf( lpszPath, "DosSignature is 0x%x!", DosSignature );
                    455: 
                    456:   return( 0 );
                    457: }
                    458: 
                    459: 
                    460: #if( MIPS == 1 )
                    461: // ************************************************************************
                    462: // FUNCTION : SkipThreadBreakPoint( DWORD );
                    463: // PURPOSE  : Skip over the break point instruction belonging to
                    464: //            dwThreadId
                    465: // COMMENTS : Only the MIPS R4000 requires this
                    466: // ************************************************************************
                    467: BOOL
                    468: SkipBreakPoint( DWORD dwThreadId )
                    469: {
                    470:   CONTEXT Context;
                    471:   PNODE   ThreadNode;
                    472:   PNODE   InputNode;
                    473: 
                    474:   CreateNode( &ProcessList, &InputNode );
                    475:   ThreadNode = InputNode;
                    476:   (InputNode->NodeData).dwThreadId = dwThreadId;
                    477: 
                    478:   if( GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 ) == NO_MATCH_ERROR ) {
                    479:     ListBoxInsert( hWndDebugList, &MaxStrLen, "--> Error: Node not found" );
                    480:     return( FALSE );
                    481:   }
                    482: 
                    483:   Context.ContextFlags = CONTEXT_CONTROL;
                    484: 
                    485:   if( !GetThreadContext( (ThreadNode->NodeData).hThread, &Context ) ) {
                    486:     char szTempBuf[64];
                    487: 
                    488:     sprintf(szTempBuf, "--> Error: dwThreadId = 0x%8.8lx", dwThreadId );
                    489:     ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf );
                    490:     sprintf(szTempBuf, "--> Error: GetThreadContext( %lx ) failed, error 0x%8.8lx",
                    491:       (DWORD) (ThreadNode->NodeData).hThread,
                    492:       (DWORD) GetLastError() );
                    493:     ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf);
                    494: 
                    495:     return( FALSE );
                    496:   }
                    497: 
                    498:   Context.Fir += 4L;  // Fir is the PC (program counter)
                    499:                       // BREAK (breakpoint instruction) occupies 4 bytes
                    500: 
                    501:   // -----------------------------------------------------------------------
                    502:   //  Below would be equvalent for the Intel 80x86 if it were necessary
                    503:   //  Context.Eip += 2L;  // Eip is the PC (program counter)
                    504:   //                      // int 3 (breakpoint instruction) occupies 2 bytes
                    505:   // -----------------------------------------------------------------------
                    506: 
                    507:   SetThreadContext( (ThreadNode->NodeData).hThread, &Context );
                    508:   DestroyNode( InputNode );
                    509: 
                    510:   return( TRUE );
                    511: }
                    512: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.