Example #1
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...\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;
}
Example #2
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;
}