⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbgmain.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -