📄 dbgmain.c
字号:
(LPVOID)pos, (LPVOID)dllInfo->name, 510,
&len);
dllInfo->name[len] = 0;
if (dllInfo->fUnicode)
{
for (i = 0; i < len; i += 2)
dllInfo->name[i / 2] = dllInfo
->name[i];
}
dllInfo->dbg_info = GetDebugInfo((LPVOID)
dllInfo->base, dllInfo->name, TRUE);
if (dllInfo->dbg_info)
ava = " ...Debug info loaded";
sprintf(buf, "DLL Loading: %s%s\r\n",
dllInfo->name, ava);
SendMessage(hwndError, WM_SETTEXT,
ERR_DEBUG_WINDOW, (LPARAM)buf);
}
}
while (*info && (unsigned)(*info)->base < (unsigned)
stDE.u.LoadDll.lpBaseOfDll)
info = &(*info)->next;
dllInfo->next = *info;
*info = dllInfo;
if (dllInfo->dbg_info && (selectedProject
->buildFlags &BF_BREAKDLL))
{
int addr = GetMainAddress(dllInfo->dbg_info);
if (addr)
{
BREAKPOINT **p =
&DebugProcess.breakpoints.next;
while (*p)
p = &(*p)->next;
*p = calloc(sizeof(BREAKPOINT), 1);
if (*p)
{
GetBreakpointLine(addr, &(*p)->module,
&(*p)->linenum);
(*p)->address = addr;
dllInfo->breakpoint = addr;
for (i = 0; i < numberofdrawwindows; i
++)
InvalidateRect(children[i], 0, 0);
}
}
}
// set breakpoints for recently loaded DLL.
TagRegenBreakPoints();
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
SetBreakPoints(DebugProcess.idProcess, FALSE);
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_LOWEST);
}
dwContinueStatus = DBG_CONTINUE;
}
break;
case UNLOAD_DLL_DEBUG_EVENT:
{
DLL_INFO **info = &DebugProcess.dll_info;
while (*info && (*info)->base != (int)
stDE.u.UnloadDll.lpBaseOfDll)
info = &(*info)->next;
if (*info)
{
DLL_INFO *x = (*info);
sprintf(buf, "DLL Unloading: %s\r\n", (*info)->name)
;
SendMessage(hwndError, WM_SETTEXT, ERR_DEBUG_WINDOW,
(LPARAM)buf);
*info = (*info)->next;
FreeDebugInfo(x->dbg_info);
free(x);
}
dwContinueStatus = DBG_CONTINUE;
}
break;
case CREATE_THREAD_DEBUG_EVENT:
{
char name[256];
th = &DebugProcess.threads;
while (*th)
th = &(*th)->next;
*th = malloc(sizeof(THREAD));
if (*th)
{
memset(*th, 0, sizeof(THREAD));
(*th)->idThread = stDE.dwThreadId;
(*th)->hThread = stDE.u.CreateThread.hThread;
}
if (!FindFunctionName(name, (int)
stDE.u.CreateThread.lpStartAddress))
name[0] = 0;
sprintf(buf, "Thread creation: %08x %08x %s\r\n",
stDE.dwThreadId, stDE.u.CreateThread.lpStartAddress,
name);
if (*th)
strcpy((*th)->name, name);
SendMessage(hwndError, WM_SETTEXT, ERR_DEBUG_WINDOW,
(LPARAM)buf);
if (isTerminating)
SuspendThread(stDE.u.CreateThread.hThread);
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
(*th)->regs.Dr7 = 0;
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
dwContinueStatus = DBG_CONTINUE;
}
break;
case EXIT_THREAD_DEBUG_EVENT:
{
th = &DebugProcess.threads;
while ((*th) && (*th)->idThread != stDE.dwThreadId)
th = &(*th)->next;
if (*th)
{
THREAD *p = *th;
sprintf(buf, "Thread exit: %08x %s\r\n", p
->idThread, p->name);
SendMessage(hwndError, WM_SETTEXT, ERR_DEBUG_WINDOW,
(LPARAM)buf);
CloseHandle(p->hThread);
(*th) = (*th)->next;
free(p);
}
dwContinueStatus = DBG_CONTINUE;
}
break;
case OUTPUT_DEBUG_STRING_EVENT:
{
char buf2[256];
int len = stDE.u.DebugString.nDebugStringLength;
if (len > 255)
len = 255;
memset(buf2, 0, 256);
ReadProcessMemory(DebugProcess.hProcess,
stDE.u.DebugString.lpDebugStringData, buf2, len, 0);
sprintf(buf,
"\r\n********OUTPUT DEBUG STRING: ********\r\n%s\r\n****************\r\n", buf2);
SendMessage(hwndError, WM_SETTEXT, ERR_DEBUG_WINDOW,
(LPARAM)buf);
dwContinueStatus = DBG_CONTINUE;
}
break;
case RIP_EVENT:
{
dwContinueStatus = DBG_CONTINUE;
}
break;
case EXCEPTION_DEBUG_EVENT:
{
switch (stDE.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_SINGLE_STEP:
ClearTraceFlag(stDE.dwProcessId, stDE.dwThreadId);
#ifdef HBREAK
if (hbp = hbpCheck(stDE.dwThreadId))
{
ContinueStep = FALSE;
}
else
#endif
if (ContinueStep)
{
if (!SittingOnBreakPoint(&stDE))
{
ContinueStep = FALSE;
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
SetBreakPoints(stDE.dwProcessId, bSeenMain);
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
dwContinueStatus = DBG_CONTINUE;
break;
}
}
case EXCEPTION_BREAKPOINT:
bSeenMain = bSetMainBP;
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
ClearBreakPoints(stDE.dwProcessId);
if (((int)
stDE.u.Exception.ExceptionRecord.ExceptionAddress != DebugProcess.breakpoints.address) || stDE.dwThreadId == DebugProcess.idTempBpThread)
{
if (bSeenInitialBP)
{
if
(stDE.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT && (isLocalBreakPoint((int)stDE.u.Exception.ExceptionRecord.ExceptionAddress) || (int)stDE.u.Exception.ExceptionRecord.ExceptionAddress == DebugProcess.breakpoints.address))
{
StoppedThread->regs.Eip--;
}
if (StoppedThread == DebugProcess.threads
&& StoppedThread->oldaddr)
{
StoppedThread->regs.Eip = StoppedThread
->oldaddr;
stDE.u.Exception.ExceptionRecord.ExceptionAddress = (LPVOID)StoppedThread->oldaddr;
while (StoppedThread->suspcount)
{
StoppedThread->suspcount--;
SuspendThread(StoppedThread
->hThread);
}
StoppedThread->oldaddr = 0;
freeBreakPoint(DebugProcess.hProcess,
&StoppedThread->breakpoint);
}
ClearTempBreakPoint(stDE.dwProcessId);
if (!terminating && uState != SteppingOut
&& !IsStepping(&stDE))
{
ProcessToTop(GetCurrentProcessId());
dwContinueStatus = HandleBreakpoint
(&stDE);
ProcessToTop(stDE.dwProcessId);
}
else
dwContinueStatus = DBG_CONTINUE;
}
else
{
DWORD addr;
bSeenInitialBP = TRUE;
/* This had to be deferred for win2K */
DebugProcess.ExitAddr =
FindExitProcessAddress
(DebugProcess.hProcess, base);
if (addr = GetMainAddress
(DebugProcess.dbg_info))
{
if (stopWinMain)
SetTempBreakPoint(stDE.dwProcessId,
stDE.dwThreadId, addr);
}
else
{
ClearTempBreakPoint(stDE.dwProcessId);
if (stopWinMain)
SetTempBreakPoint(stDE.dwProcessId,
stDE.dwThreadId, GetEntryPoint()
);
}
bSetMainBP = TRUE;
dwContinueStatus = DBG_CONTINUE;
}
isSteppingOut(&stDE);
}
else
{
dwContinueStatus = DBG_CONTINUE;
}
// WIN32 doesn't support the DBG_TERMINATE_PROCESS flag, so we
// have to go to some effort to get the process terminated.
// This started at process creation time, when we found the address
// of the ExitProcess function if there was one.
doterm: if (dwContinueStatus ==
DBG_TERMINATE_PROCESS)
{
// suspend all the threads so we won't get
// exceptions while we are closing. We have
// to defer the actual close until no more events
// are coming in to prevent a clash between
// the shutdown and threads that are just
// starting
THREAD *th = DebugProcess.threads;
while (th)
{
SuspendThread(th->hThread);
th = th->next;
}
terminating = isTerminating = TRUE;
dwContinueStatus = DBG_CONTINUE;
}
if (!SingleStepping && !isTerminating)
if (SittingOnBreakPoint(&stDE))
{
ContinueStep = TRUE;
SingleStep(stDE.dwProcessId, stDE.dwThreadId);
}
else
{
SetBreakPoints(stDE.dwProcessId, bSeenMain);
}
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
break;
default:
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
ClearBreakPoints(stDE.dwProcessId);
ProcessToTop(GetCurrentProcessId());
dwContinueStatus = HandleException(&stDE);
if (dwContinueStatus == DBG_TERMINATE_PROCESS)
goto doterm;
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
ProcessToTop(stDE.dwProcessId);
break;
}
}
break;
// For any other events, just continue on.
default:
{
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
}
break;
}
}
else
{
dwContinueStatus = DBG_CONTINUE;
bContinue = TRUE;
if (terminating)
{
// if we get here all threads have been stopped, and there
// has been a 0.5 second delay since the last debug event.
// We assume there are no more debug events sitting there
// if there were things become unstable when we exit
terminating = FALSE;
if (DebugProcess.ExitAddr)
{
// Blast an exit process call into the main thread, and resume it
GetRegs(DebugProcess.idProcess, DebugProcess.threads
->idThread);
BlastExitProcFunc(DebugProcess.hProcess,
DebugProcess.idProcess, StoppedThread->idThread,
DebugProcess.ExitAddr);
SetRegs(DebugProcess.idProcess, DebugProcess.threads
->idThread);
while ((int)ResumeThread(StoppedThread->hThread) > 1)
;
PostThreadMessage(stDE.dwThreadId, WM_NULL, 0, 0);
}
else
{
// This should never happen, unless we don't have ExitProcess
// in the executable file. Our tools don't do that.
TerminateProcess(DebugProcess.hProcess, 0);
ExtendedMessageBox("Forced Termination", MB_SETFOREGROUND |
MB_SYSTEMMODAL,
"A forced termination has been used.\n This may leave the system in an unstable state.");
}
}
}
// Pass on to the operating system.
ContinueDebugEvent(stDE.dwProcessId, stDE.dwThreadId, dwContinueStatus);
}
CloseHandle(StartupSem);
CloseHandle(BreakpointSem);
selectedProject->dbgview = 0;
selectedProject->dbgview |= dmgrHideWindow(DID_ASMWND, TRUE) << DID_ASMWND;
selectedProject->dbgview |= dmgrHideWindow(DID_WATCHWND, TRUE) <<
DID_WATCHWND;
selectedProject->dbgview |= dmgrHideWindow(DID_MEMWND, TRUE) << DID_MEMWND;
selectedProject->dbgview |= dmgrHideWindow(DID_STACKWND, TRUE) <<
DID_STACKWND;
selectedProject->dbgview |= dmgrHideWindow(DID_THREADWND, TRUE) <<
DID_THREADWND;
selectedProject->dbgview |= dmgrHideWindow(DID_REGWND, TRUE) << DID_REGWND;
ProcessToTop(GetCurrentProcessId());
uState = notDebugging;
PostMessage(hwndRegister, WM_COMMAND, ID_SETADDRESS, 0);
// PostMessage(hwndWatch,WM_ADDWATCH,0,0) ;
InvalidateRect(hwndRegister, 0, TRUE);
i = SendMessage(hwndToolDebug, TB_GETSTATE, IDM_STARTSTOP, 0);
SendMessage(hwndToolDebug, TB_SETSTATE, IDM_STARTSTOP, MAKELONG
(~TBSTATE_CHECKED &i, 0));
RedrawAllBreakpoints();
PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -