📄 dbgmain.c
字号:
else
return 0;
// couldn't locate line, invalid line...
}
}
//-------------------------------------------------------------------------
void dbgClearBreakPoint(char *name, int linenum)
{
BREAKPOINT **p = &DebugProcess.breakpoints.next;
if (uState == notDebugging)
return ;
if (!name)
{
// from ASM window
int addr = linenum;
while (*p)
{
if ((*p)->address == addr)
{
BREAKPOINT *q = *p;
*p = (*p)->next;
if (uState == Running)
freeBreakPoint(DebugProcess.hProcess, q);
free(q->extra);
free(q);
InvalidateRect(hwndASM, 0, 0);
return ;
}
p = &(*p)->next;
}
}
else
{
int addr = GetBreakpointAddress(name, &linenum, FALSE);
if (addr)
{
while (*p)
{
if ((*p)->address == addr)
{
BREAKPOINT *q = *p;
*p = (*p)->next;
if (uState == Running)
freeBreakPoint(DebugProcess.hProcess, q);
free(q->extra);
free(q);
if (hwndASM)
InvalidateRect(hwndASM, 0, 0);
return ;
}
p = &(*p)->next;
}
}
}
}
//-------------------------------------------------------------------------
void SetBP(DEBUG_EVENT *dbe)
{
BREAKPOINT **p = &DebugProcess.breakpoints.next;
if (hwndASM && GetFocus() == hwndASM)
{
int addr = SendMessage(hwndASM, WM_GETCURSORADDRESS, 0, 0);
Tag(TAG_BP, 0, addr, 0, 0, 0, 0);
if (uState == Running)
allocBreakPoint(DebugProcess.hProcess, *p);
}
else
{
HWND hWnd = GetFocus();
int i;
for (i = 0; i < numberofdrawwindows; i++)
{
DWINFO *ptr = (DWINFO*)GetWindowLong(children[i], 0);
if (ptr->dwHandle == hWnd)
{
int addr, linenum;
SendMessage(ptr->dwHandle, EM_GETSEL, (WPARAM) &linenum, 0);
linenum = SendMessage(ptr->dwHandle, EM_EXLINEFROMCHAR, 0,
linenum) + 1;
Tag(TAG_BP, ptr->dwName, linenum, 0, 0, 0, 0);
break;
}
}
}
InvalidateRect(hwndASM, 0, 0);
}
//-------------------------------------------------------------------------
int isSteppingOut(DEBUG_EVENT *dbe)
{
if (uState == SteppingOut)
{
unsigned char bf = 0;
ReadProcessMemory(DebugProcess.hProcess, (LPVOID)StoppedThread
->regs.Eip, (LPVOID) &bf, 1, 0);
if (bf == 0xc2 || bf == 0xc3)
{
SingleStep(dbe->dwProcessId, dbe->dwThreadId);
uState = FinishStepOut;
}
else
DoStepOver(dbe);
return TRUE;
}
return FALSE;
}
//-------------------------------------------------------------------------
void StopRunning(int newState)
{
THREAD *th = DebugProcess.threads;
if (uState == Running || uState == SteppingOut || uState == StepInOut)
{
HANDLE hThisThread = GetCurrentThread();
int iOldPriority = GetThreadPriority(hThisThread);
int oldaddr;
ProcessToTop(GetCurrentProcessId());
SetThreadPriority(hThisThread, REALTIME_PRIORITY_CLASS +
THREAD_PRIORITY_BELOW_NORMAL);
while (th)
{
SuspendThread(th->hThread);
th = th->next;
}
GetRegs(0, 0);
th = DebugProcess.threads;
th->oldaddr = th->regs.Eip;
th->regs.Eip = th->breakpoint.address = DebugProcess.dbg_info->base;
th->breakpoint.active = FALSE;
allocBreakPoint(DebugProcess.hProcess, &th->breakpoint);
PostThreadMessage(th->idThread, WM_NULL, 0, 0);
SetRegs(0, 0);
th->suspcount = ResumeThread(th->hThread) - 1;
if ((int)th->suspcount < 0)
th->suspcount = 0;
if (th->suspcount)
while (ResumeThread(th->hThread) > 1)
;
th = th->next;
while (th)
{
ResumeThread(th->hThread);
th = th->next;
}
if (newState != nullState)
uState = newState;
/* At this point it still may not stop if there is a deadlock
* condition, requires further work
*/
SetThreadPriority(hThisThread, iOldPriority);
ProcessToTop(DebugProcess.idProcess);
}
}
//-------------------------------------------------------------------------
void abortDebugThread(void)
{
int i = 0;
if (uState != notDebugging)
{
if (uState == atBreakpoint || uState == atException)
{
uState = Aborting;
SaveRegisterContext();
ReleaseSemaphore(BreakpointSem, 1, 0);
}
else
{
StopRunning(Aborting);
uState = Aborting;
SaveRegisterContext();
ReleaseSemaphore(BreakpointSem, 1, 0);
}
while (uState != notDebugging)
{
if (++i >= 100)
{
ExtendedMessageBox("Debug Alert", MB_SETFOREGROUND |
MB_SYSTEMMODAL, "Internal error - debugger is not aborting")
;
return ;
}
Sleep(100);
}
}
i = SendMessage(hwndToolDebug, TB_GETSTATE, IDM_STARTSTOP, 0);
SendMessage(hwndToolDebug, TB_SETSTATE, IDM_STARTSTOP, MAKELONG
(~TBSTATE_CHECKED &i, 0));
}
//-------------------------------------------------------------------------
void abortDebug(void)
{
DWORD threadhand;
CloseHandle(CreateThread(0, 0, (LPTHREAD_START_ROUTINE)abortDebugThread,
(LPVOID)0, 0, &threadhand));
}
//-------------------------------------------------------------------------
void StartDebug(char *cmd)
{
STARTUPINFO stStartInfo;
PROCESS_INFORMATION stProcessInfo;
DEBUG_EVENT stDE;
BOOL bSeenInitialBP = FALSE;
BOOL bContinue = TRUE;
BOOL bSeenMain = FALSE, bSetMainBP = FALSE;
DWORD dwContinueStatus;
BOOL bRet;
BOOL ContinueStep = FALSE;
BREAKPOINT **bp;
THREAD **th;
int val, i, hbp;
BOOL terminating = FALSE, isTerminating = FALSE;
int base = 0;
char buf[512];
memset(&stStartInfo, 0, sizeof(STARTUPINFO));
memset(&stProcessInfo, 0, sizeof(PROCESS_INFORMATION));
stStartInfo.cb = sizeof(STARTUPINFO);
bRet = CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE |
DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &stStartInfo,
&stProcessInfo);
if (!bRet)
{
ReleaseSemaphore(StartupSem, 1, 0);
ExtendedMessageBox("Debugger", MB_SETFOREGROUND | MB_SYSTEMMODAL,
"Could not execute %s.", cmd);
return ;
}
Sleep(500); /* Needed to make things happy */
uState = Running;
InvalidateRect(hwndRegister, 0, TRUE);
CloseHandle(stProcessInfo.hThread);
CloseHandle(stProcessInfo.hProcess);
ReleaseSemaphore(StartupSem, 1, 0);
if (selectedProject->dbgview &(1 << DID_ASMWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWASM, 0);
if (selectedProject->dbgview &(1 << DID_WATCHWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWWATCH, 0);
if (selectedProject->dbgview &(1 << DID_MEMWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWDUMP, 0);
if (selectedProject->dbgview &(1 << DID_STACKWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWSTACK, 0);
if (selectedProject->dbgview &(1 << DID_THREADWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWTHREAD, 0);
if (selectedProject->dbgview &(1 << DID_REGWND))
PostMessage(hwndFrame, WM_COMMAND, IDM_VIEWREGISTER, 0);
SendMessage(hwndError, WM_SELERRWINDOW, 0, ERR_DEBUG_WINDOW);
// Loop until told to stop.
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
while (TRUE == bContinue)
{
// Pause until a debug event notification happens.
bContinue = WaitForDebugEvent(&stDE, 500);
if (bContinue)
{
switch (stDE.dwDebugEventCode)
{
case CREATE_PROCESS_DEBUG_EVENT:
{
THREAD *newThread = malloc(sizeof(THREAD));
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_NORMAL);
// Save the handle information needed for later.
DebugProcess.hProcess =
stDE.u.CreateProcessInfo.hProcess;
DebugProcess.idProcess = stDE.dwProcessId;
memset(newThread, 0, sizeof(*newThread));
newThread->hThread = stDE.u.CreateProcessInfo.hThread;
newThread->idThread = stDE.dwThreadId;
strcpy(newThread->name, "main thread");
DebugProcess.threads = newThread;
dwContinueStatus = DBG_CONTINUE;
DebugProcess.dbg_info = GetDebugInfo
(stDE.u.CreateProcessInfo.lpBaseOfImage, cmd, FALSE)
;
base = stDE.u.CreateProcessInfo.lpBaseOfImage;
/* next line has to be deferred to the init bp */
TagRegenBreakPoints();
GetRegs(stDE.dwProcessId, stDE.dwThreadId);
newThread->regs.Dr7 = 0;
SetBreakPoints(DebugProcess.idProcess, FALSE);
SetRegs(stDE.dwProcessId, stDE.dwThreadId);
CloseHandle(stDE.u.CreateProcessInfo.hFile);
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_LOWEST);
dwContinueStatus = DBG_CONTINUE;
}
break;
case EXIT_PROCESS_DEBUG_EVENT:
{
DLL_INFO *dllInfo = DebugProcess.dll_info;
#ifdef HBREAK
hbpEnd();
#endif
DebugProcess.dll_info = 0;
if (uState != Aborting)
ExtendedMessageBox("Debugger", MB_SYSTEMMODAL |
MB_SETFOREGROUND, "Process has ended");
FreeDebugInfo(DebugProcess.dbg_info);
DebugProcess.dbg_info = 0;
CloseHandle(DebugProcess.hProcess);
// Created threads may not exit gracefully
// in fact one at least will always be left
while (DebugProcess.threads)
{
THREAD *v = DebugProcess.threads;
DebugProcess.threads = v->next;
CloseHandle(v->hThread);
free(v);
}
PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
// System dlls don't get an unload message
while (dllInfo)
{
DLL_INFO *x = dllInfo->next;
FreeDebugInfo(dllInfo->dbg_info);
free(dllInfo);
dllInfo = x;
}
bp = &DebugProcess.breakpoints.next;
while (*bp)
{
BREAKPOINT *q = *bp;
*bp = (*bp)->next;
free(q);
}
memset(&DebugProcess, 0, sizeof(PROCESS));
bContinue = FALSE;
dwContinueStatus = DBG_CONTINUE;
}
break;
case LOAD_DLL_DEBUG_EVENT:
{
LPVOID pos;
int len;
DLL_INFO *dllInfo = (DLL_INFO*)calloc(sizeof(DLL_INFO),
1);
if (dllInfo)
{
DLL_INFO **info = &DebugProcess.dll_info;
dllInfo->dbg_info = 0;
dllInfo->base = stDE.u.LoadDll.lpBaseOfDll;
pos = stDE.u.LoadDll.lpImageName;
dllInfo->fUnicode = stDE.u.LoadDll.fUnicode;
dllInfo->hFile = stDE.u.LoadDll.hFile;
CloseHandle(dllInfo->hFile);
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_NORMAL);
if (pos)
{
ReadProcessMemory(DebugProcess.hProcess, pos,
(LPVOID) &pos, 4, &len);
if (pos)
{
char *ava = "";
ReadProcessMemory(DebugProcess.hProcess,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -