int RunDebugger() { if (!gpSrv->DbgInfo.pDebugTreeProcesses) { gpSrv->DbgInfo.pDebugTreeProcesses = (MMap<DWORD,CEDebugProcessInfo>*)calloc(1,sizeof(*gpSrv->DbgInfo.pDebugTreeProcesses)); gpSrv->DbgInfo.pDebugTreeProcesses->Init(1024); } UpdateDebuggerTitle(); // Если это новая консоль - увеличить ее размер, для удобства if (IsWindowVisible(ghConWnd)) { HANDLE hCon = ghConOut; CONSOLE_SCREEN_BUFFER_INFO csbi = {}; GetConsoleScreenBufferInfo(hCon, &csbi); if (csbi.dwSize.X < 260) { COORD crNewSize = {260, 9999}; SetConsoleScreenBufferSize(ghConOut, crNewSize); } //if ((csbi.srWindow.Right - csbi.srWindow.Left + 1) < 120) //{ // COORD crMax = GetLargestConsoleWindowSize(hCon); // if ((crMax.X - 10) > (csbi.srWindow.Right - csbi.srWindow.Left + 1)) // { // COORD crSize = {((int)((crMax.X - 15)/10))*10, min(crMax.Y, (csbi.srWindow.Bottom - csbi.srWindow.Top + 1))}; // SMALL_RECT srWnd = {0, csbi.srWindow.Top, crSize.X - 1, csbi.srWindow.Bottom}; // MONITORINFO mi = {sizeof(mi)}; // GetMonitorInfo(MonitorFromWindow(ghConWnd, MONITOR_DEFAULTTONEAREST), &mi); // RECT rcWnd = {}; GetWindowRect(ghConWnd, &rcWnd); // SetWindowPos(ghConWnd, NULL, min(rcWnd.left,(mi.rcWork.left+50)), rcWnd.top, 0,0, SWP_NOSIZE|SWP_NOZORDER); // SetConsoleSize(9999, crSize, srWnd, "StartDebugger"); // } //} } // Вывести в консоль информацию о версии. PrintVersion(); #ifdef SHOW_DEBUG_STARTED_MSGBOX wchar_t szInfo[128]; StringCchPrintf(szInfo, countof(szInfo), L"Attaching debugger...\nConEmuC PID = %u\nDebug PID = %u", GetCurrentProcessId(), gpSrv->dwRootProcess); MessageBox(GetConEmuHWND(2), szInfo, L"ConEmuC.Debugger", 0); #endif //if (!DebugActiveProcess(gpSrv->dwRootProcess)) //{ // DWORD dwErr = GetLastError(); // _printf("Can't start debugger! ErrCode=0x%08X\n", dwErr); // return CERR_CANTSTARTDEBUGGER; //} //// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело //// к закрытию "отлаживаемой" программы //pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop"); //pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit"); //if (pfnDebugSetProcessKillOnExit) // pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/); //gpSrv->DbgInfo.bDebuggerActive = TRUE; //PrintDebugInfo(); if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL) { int iAttachRc = AttachRootProcessHandle(); if (iAttachRc != 0) return iAttachRc; } else { _ASSERTE(!gpSrv->DbgInfo.bDebuggerActive); } _ASSERTE(((gpSrv->hRootProcess!=NULL) || (gpSrv->DbgInfo.pszDebuggingCmdLine!=NULL)) && "Process handle must be opened"); gpSrv->DbgInfo.hDebugReady = CreateEvent(NULL, FALSE, FALSE, NULL); // Перенес обработку отладочных событий в отдельную нить, чтобы случайно не заблокироваться с главной gpSrv->DbgInfo.hDebugThread = CreateThread(NULL, 0, DebugThread, NULL, 0, &gpSrv->DbgInfo.dwDebugThreadId); HANDLE hEvents[2] = {gpSrv->DbgInfo.hDebugReady, gpSrv->DbgInfo.hDebugThread}; DWORD nReady = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE); if (nReady != WAIT_OBJECT_0) { DWORD nExit = 0; GetExitCodeThread(gpSrv->DbgInfo.hDebugThread, &nExit); return nExit; } gpszRunCmd = (wchar_t*)calloc(1,2); if (!gpszRunCmd) { _printf("Can't allocate 1 wchar!\n"); return CERR_NOTENOUGHMEM1; } gpszRunCmd[0] = 0; gpSrv->DbgInfo.bDebuggerActive = TRUE; // And wait for debugger thread completion _ASSERTE(gnRunMode == RM_UNDEFINED); DWORD nDebugThread = WaitForSingleObject(gpSrv->DbgInfo.hDebugThread, INFINITE); _ASSERTE(nDebugThread == WAIT_OBJECT_0); UNREFERENCED_PARAMETER(nDebugThread); gbInShutdown = TRUE; return 0; }
int RunDebugger() { if (!gpSrv->DbgInfo.pDebugTreeProcesses) { gpSrv->DbgInfo.pDebugTreeProcesses = (MMap<DWORD,CEDebugProcessInfo>*)calloc(1,sizeof(*gpSrv->DbgInfo.pDebugTreeProcesses)); gpSrv->DbgInfo.pDebugTreeProcesses->Init(1024); } UpdateDebuggerTitle(); // Если это новая консоль - увеличить ее размер, для удобства if (IsWindowVisible(ghConWnd)) { HANDLE hCon = ghConOut; CONSOLE_SCREEN_BUFFER_INFO csbi = {}; GetConsoleScreenBufferInfo(hCon, &csbi); if (csbi.dwSize.X < 260) { COORD crNewSize = {260, 9999}; SetConsoleScreenBufferSize(ghConOut, crNewSize); } //if ((csbi.srWindow.Right - csbi.srWindow.Left + 1) < 120) //{ // COORD crMax = GetLargestConsoleWindowSize(hCon); // if ((crMax.X - 10) > (csbi.srWindow.Right - csbi.srWindow.Left + 1)) // { // COORD crSize = {((int)((crMax.X - 15)/10))*10, min(crMax.Y, (csbi.srWindow.Bottom - csbi.srWindow.Top + 1))}; // SMALL_RECT srWnd = {0, csbi.srWindow.Top, crSize.X - 1, csbi.srWindow.Bottom}; // MONITORINFO mi = {sizeof(mi)}; // GetMonitorInfo(MonitorFromWindow(ghConWnd, MONITOR_DEFAULTTONEAREST), &mi); // RECT rcWnd = {}; GetWindowRect(ghConWnd, &rcWnd); // SetWindowPos(ghConWnd, NULL, min(rcWnd.left,(mi.rcWork.left+50)), rcWnd.top, 0,0, SWP_NOSIZE|SWP_NOZORDER); // SetConsoleSize(9999, crSize, srWnd, "StartDebugger"); // } //} } // Вывести в консоль информацию о версии. PrintVersion(); #ifdef SHOW_DEBUG_STARTED_MSGBOX wchar_t szInfo[128]; StringCchPrintf(szInfo, countof(szInfo), L"Attaching debugger...\n" CE_CONEMUC_NAME_W " PID = %u\nDebug PID = %u", GetCurrentProcessId(), gpSrv->dwRootProcess); MessageBox(GetConEmuHWND(2), szInfo, CE_CONEMUC_NAME_W L".Debugger", 0); #endif if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL) { int iAttachRc = AttachRootProcessHandle(); if (iAttachRc != 0) return iAttachRc; } else { _ASSERTE(!gpSrv->DbgInfo.bDebuggerActive); } gpszRunCmd = (wchar_t*)calloc(1,sizeof(*gpszRunCmd)); if (!gpszRunCmd) { _printf("Can't allocate 1 wchar!\n"); return CERR_NOTENOUGHMEM1; } _ASSERTE(((gpSrv->hRootProcess!=NULL) || (gpSrv->DbgInfo.pszDebuggingCmdLine!=NULL)) && "Process handle must be opened"); // Если просили сделать дамп нескольких процессов - нужно сразу уточнить его тип if (gpSrv->DbgInfo.bDebugMultiProcess && (gpSrv->DbgInfo.nDebugDumpProcess == 1)) { // 2 - minidump, 3 - fulldump int nConfirmDumpType = ConfirmDumpType(gpSrv->dwRootProcess, NULL); if (nConfirmDumpType < 2) { // Отмена return CERR_CANTSTARTDEBUGGER; } gpSrv->DbgInfo.nDebugDumpProcess = nConfirmDumpType; } // gpSrv->DbgInfo.bDebuggerActive must be set in DebugThread // Run DebugThread gpSrv->DbgInfo.hDebugReady = CreateEvent(NULL, FALSE, FALSE, NULL); // Перенес обработку отладочных событий в отдельную нить, чтобы случайно не заблокироваться с главной gpSrv->DbgInfo.hDebugThread = CreateThread(NULL, 0, DebugThread, NULL, 0, &gpSrv->DbgInfo.dwDebugThreadId); HANDLE hEvents[2] = {gpSrv->DbgInfo.hDebugReady, gpSrv->DbgInfo.hDebugThread}; DWORD nReady = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE); if (nReady != WAIT_OBJECT_0) { DWORD nExit = 0; GetExitCodeThread(gpSrv->DbgInfo.hDebugThread, &nExit); return nExit; } // gpSrv->DbgInfo.bDebuggerActive was set in DebugThread // And wait for debugger thread completion _ASSERTE(gnRunMode == RM_UNDEFINED); DWORD nDebugThread = WaitForSingleObject(gpSrv->DbgInfo.hDebugThread, INFINITE); _ASSERTE(nDebugThread == WAIT_OBJECT_0); UNREFERENCED_PARAMETER(nDebugThread); gbInShutdown = TRUE; return 0; }