Esempio n. 1
0
	void IProgramObject::RecompileIfNeeded(bool validate)
	{
		if (curFlagsHash != 0 && GetHash() == curFlagsHash)
			return;

		// NOTE: this does not preserve the #version pragma
		const std::string definitionFlags = GetString();
		for (IShaderObject*& so: shaderObjs) {
			so->SetDefinitions(definitionFlags);
		}

		Reload(curFlagsHash == 0, validate);
		PrintDebugInfo();
	}
Esempio n. 2
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	//DWORD nExternalExitCode = -1;
	wchar_t szInfo[1024];

	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			lstrcpyn(szInfo+lstrlen(szInfo), gpSrv->DbgInfo.pszDebuggingCmdLine, 400);
			wcscat_c(szInfo, L"\n");
			_wprintf(szInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();
	}


	/* ************************* */
	int iDbgIdx = 0, iAttachedCount = 0;
	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		bool bFirstPID = ((iDbgIdx++) == 0);
		if (bFirstPID)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}
	

		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					if (bFirstPID)
						return CERR_CANTSTARTDEBUGGER;
					else
						continue;
				}

				wchar_t szExe[MAX_PATH+16];
				wchar_t szCmdLine[MAX_PATH*2];
				if (GetModuleFileName(NULL, szExe, countof(szExe)-16))
				{
					wchar_t* pszName = (wchar_t*)PointToName(szExe);
					_wcscpy_c(pszName, 16, (nBits == 32) ? L"ConEmuC.exe" : L"ConEmuC64.exe");
					_wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine))
						L"\"%s\" /DEBUGPID=%u %s", szExe, nDbgProcessID,
						(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L"/DUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L"/MINIDUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L"/FULLDUMP" : L"");

					STARTUPINFO si = {sizeof(si)};
					PROCESS_INFORMATION pi = {};
					if (CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
					{
						// Ждать НЕ будем, сразу на выход

						//HANDLE hEvents[2] = {pi.hProcess, ghExitQueryEvent};
						//nWait = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE);
						//if (nWait == WAIT_OBJECT_0)
						//{
						//	//GetExitCodeProcess(pi.hProcess, &nExternalExitCode);
						//	nExternalExitCode = 0;
						//}

						//CloseHandle(pi.hProcess);
						//CloseHandle(pi.hThread);

						//if (nExternalExitCode == 0)
						//{
						//	goto done;
						//}

						// Может там еще процессы в списке на дамп?
						continue;
					}
					else
					{
						DWORD dwErr = GetLastError();
						_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger '%s'. ErrCode=0x%08X\n",
							szCmdLine, dwErr);
						_wprintf(szInfo);
						if (bFirstPID)
							return CERR_CANTSTARTDEBUGGER;
						else
							continue;
					}
				}


				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Bits are incompatible. Can't debug '%s' PID=%i\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID);
				_wprintf(szInfo);
				if (bFirstPID)
					return CERR_CANTSTARTDEBUGGER;
				else
					continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (!DebugActiveProcess(nDbgProcessID))
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);
				return CERR_CANTSTARTDEBUGGER;
			}
		}

		iAttachedCount++;
	}

	if (iAttachedCount == 0)
	{
		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();
	SetEvent(gpSrv->DbgInfo.hDebugReady);
	

	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}
Esempio n. 3
0
void halt(char *msg) {
    std::cout << "--" << std::endl << msg << std::endl;
    PrintDebugInfo();
    *rstack_top++ = (Value)pc - sizeof(Value);
    pc = 0;
}
Esempio n. 4
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	wchar_t szInfo[1024];
	wchar_t szPID[20];
	int iAttachedCount = 0;
	CEStr szOtherBitPids, szOtherDebugCmd;

	// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело
	// к закрытию "отлаживаемой" программы
	pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop");
	pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit");

	// Affect GetProcessHandleForDebug
	gpSrv->DbgInfo.bDebuggerActive = TRUE;

	// If dump was requested
	if (gpSrv->DbgInfo.nDebugDumpProcess)
	{
		gpSrv->DbgInfo.bUserRequestDump = TRUE;
	}

	// "/DEBUGEXE" or "/DEBUGTREE"
	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			CEStr lsInfo(lstrmerge(szInfo, gpSrv->DbgInfo.pszDebuggingCmdLine, L"\n"));
			_wprintf(lsInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();

		// Let's know that at least one process is debugging
		iAttachedCount++;
	}


	/* ************************* */
	int iDbgIdx = 0;
	bool bSetKillOnExit = true;

	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		if ((iDbgIdx++) == 0)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}


		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				// If /DEBUGEXE or /DEBUGTREE was used
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					continue;
				}

				// Добавить процесс в список для запуска альтернативного дебаггера соотвествующей битности
				// Force trailing "," even if only one PID specified ( --> bDebugMultiProcess = TRUE)
				lstrmerge(&szOtherBitPids.ms_Arg, _itow(nDbgProcessID, szPID, 10), L",");

				// Может там еще процессы в списке на дамп?
				continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (DebugActiveProcess(nDbgProcessID))
			{
				iAttachedCount++;
			}
			else
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);

				// Может другие подцепить получится?
				continue;
			}
		}

		// To avoid debugged processes killing
		if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
		{
			// affects all current and future debuggees connected to the calling thread
			if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
			{
				bSetKillOnExit = false;
			}
		}
	}

	// Different bitness, need to start appropriate debugger
	if (szOtherBitPids.ms_Arg && *szOtherBitPids.ms_Arg)
	{
		wchar_t szExe[MAX_PATH+5], *pszName;
		if (!GetModuleFileName(NULL, szExe, MAX_PATH))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) failed. ErrCode=0x%08X\n", GetLastError());
			_wprintf(szInfo);
		}
		else if (!(pszName = (wchar_t*)PointToName(szExe)))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) returns invalid path\n%s\n", szExe);
			_wprintf(szInfo);
		}
		else
		{
			*pszName = 0;
			// Reverted to current bitness
			wcscat_c(szExe, WIN3264TEST(L"ConEmuC64.exe", L"ConEmuC.exe"));

			szOtherDebugCmd.Attach(lstrmerge(L"\"", szExe, L"\" "
				L"/DEBUGPID=", szOtherBitPids.ms_Arg,
				(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L" /DUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L" /MINIDUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L" /FULLDUMP" : L""));

			STARTUPINFO si = {sizeof(si)};
			PROCESS_INFORMATION pi = {};
			if (CreateProcess(NULL, szOtherDebugCmd.ms_Arg, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
			{
				// Ждать не будем
			}
			else
			{
				DWORD dwErr = GetLastError();
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger, ErrCode=0x%08X\n", dwErr);
				CEStr lsInfo(lstrmerge(szInfo, szOtherDebugCmd, L"\n"));
				_wprintf(lsInfo);
			}
		}
	}

	//_ASSERTE(FALSE && "Continue to dump");

	// If neither /DEBUG[EXE|TREE] nor /DEBUGPID was not succeeded
	if (iAttachedCount == 0)
	{
		gpSrv->DbgInfo.bDebuggerActive = FALSE;
		return CERR_CANTSTARTDEBUGGER;
	}
	else if (iAttachedCount > 1)
	{
		_ASSERTE(gpSrv->DbgInfo.bDebugMultiProcess && "Already must be set from arguments parser");
		gpSrv->DbgInfo.bDebugMultiProcess = TRUE;
	}

	if (gpSrv->DbgInfo.bUserRequestDump)
	{
		gpSrv->DbgInfo.nWaitTreeBreaks = iAttachedCount;
	}

	/* **************** */

	// To avoid debugged processes killing (JIC, must be called already)
	if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
	{
		// affects all current and future debuggees connected to the calling thread
		if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
		{
			bSetKillOnExit = false;
		}
	}

	PrintDebugInfo();
	SetEvent(gpSrv->DbgInfo.hDebugReady);


	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}