Hello all
I get very frequently this error.
The system is Windows 10 and compiler is VS 2017.
It is annoying as only way to avoid it is restarting TheIDE or changing exe name.
Thank you.
For me it happens after previous debugging.
(I am on Windows10 64 Bit)
It happens for me when I am using MSVC17 or MSVC17 64 Bit in TheIDE and only after debugging.
In the Windows Taskmanager it can be seen, that the previously debugged process is still attached to TheIDE.
If I choose "Debug" in the Windows Taskmanager then Windows tries to attach the VSstudio debugger.
Attaching VSStudio debugger fails.
There is an error message, which says "There is another debugger attached to this process, which is not configured to handle this kind of exception".
It seems to me, it happens, when the debugee was stopped and had some kind of exception during shutdown and this probably prevented the debugger from detaching.
These are just my observations. (And educated guesses) Hope this is useful.
I have no experience with windows programming, but have used debuggers on DOS and Linux some decades ago.
if(hProcess != INVALID_HANDLE_VALUE) { DebugActiveProcessStop(processid); TerminateProcess(hProcess, 0); // Wait for max. 10 seconds. This should solve 99.9% of all problems. I hope so ;-) // TODO: If a complex unknown and possibly buggy process is terminated violently, // then the error codes are hard to interpret and should be displayed to the user. WaitForSingleObject(hProcess,10000); while(threads.GetCount()) RemoveThread(threads.GetKey(0)); // To CloseHandle UnloadModuleSymbols(); SymCleanup(hProcess); CloseHandle(hProcess); }
The TerminateProcess() systemcall is asynchronous and returns immediately, eventually before the process is actually terminated.TerminateProcess() does not kill child processes.
Also it kills all threads.
(If the documentation is correct)
I must admit, I am unable to write this debugger and I value and respect your work.
I have only focussed to this problem and went through the code step by step and had an idea what to look for: uninitialized variables, dangling pointers, buffer overflows, race conditions.
And in this case it seems to be a race condition.
So I have tried a quick patch to resolve this based on the new info. It is in the trunk.
Hi,
I did download nightly build 12584 this morning.
The sources included do not contain the updated code for Pdb::Stop()
So it is unclear to me if the binary has the updated code.
dword exitcode; int start = msecs(); while(GetExitCodeProcess(hProcess, &exitcode) && exitcode == STILL_ACTIVE && msecs(start) < 3000) Sleep(1);
I tested with 12587.
The issue is not fixed.
In the past I would get a hang up when the process locked and I had to quit TheIDE.
Now, I get a message telling me that the binary can't be opened for writing. So I guess it is an improvement. The process can't be killed by windows manager and I need to shut down TheIDE.
A few months ago I tried everything to fix this but gave up. I was using WinAPI (WaitForSingleObject if I remember correctly) to wait for the process. Yet the process would not finish and TheIDE would hang forever.
dword exitcode; int start = msecs(); while(GetExitCodeProcess(hProcess, &exitcode) && exitcode == STILL_ACTIVE && msecs(start) < 3000) Sleep(1);
This behaves better than WaitForSingleObject since it won't lock forever, but I suppose testing GetExitCodeProcess after 3 seconds will still give an active result in the case where the exe can't be written too. Maybe that should be logged somewhere and shown in TheIDE?
There must be a more aggressive way o killing a process as a fail safe?
Perhaps we could try to add Exclamation after that if process is still active - at least that would show us that this is the problem.
<--- Finished in (-5371:-45.-1), exitcode: 0 --->
mirek wrote on Thu, 29 November 2018 13:23
Perhaps we could try to add Exclamation after that if process is still active - at least that would show us that this is the problem.
Yes please!
Also, since I updated, when running command line programs with Ctrl-F5, I get this lovely output message:
Quote:<--- Finished in (-5371:-45.-1), exitcode: 0 --->
Then I did see, the Ide project had the flags "GUI" and no other.
So I recompiled Theide with flags "GUI MT", because I believe, it could be multithreaded.
Apparently this cured the problem for me. It did not happen again since 2 hours now.
Could be.
Otherwise the difference was drastic.
I had written "MT" into the compiler options.
Microsoft docs for VC 2015 say /MT will define the flag _MT and this will tell the linker to link the multithreaded libraries and/or DLLs
(I use VC2017)
Is this info outdated?
while(threads.GetCount()) RemoveThread(threads.GetKey(0)); // To CloseHandle UnloadModuleSymbols(); SymCleanup(hProcess); CloseHandle(hProcess);
if(hProcess != INVALID_HANDLE_VALUE) { DebugActiveProcessStop(processid); TerminateProcess(hProcess, 0); DWORD retval = MsgWaitForMultipleObjects( 1, //DWORD nCount, &hProcess, //const HANDLE *pHandles, true, //BOOL fWaitAll, 10000, //DWORD dwMilliseconds, 0 //DWORD dwWakeMask ); if (retval == WAIT_TIMEOUT) Exclamation("WAIT_TIMEOUT"); if (retval == WAIT_ABANDONED) Exclamation("WAIT_ABANDONED"); WaitForSingleObject(hProcess,10000); while(threads.GetCount()) RemoveThread(threads.GetKey(0)); // To CloseHandle UnloadModuleSymbols(); SymCleanup(hProcess); CloseHandle(hProcess); }
void Pdb::Stop() { DWORD retval; LOG("---------------------------------------"); LOG("terminated flag"); DUMP(terminated); if(!terminated) { terminated = true; SaveTree(); String fn = ConfigFile("TreeTypes.txt"); FileOut out(fn); for(int i = 0; i < treetype.GetCount(); i++) out << treetype.GetKey(i) << "\r\n" << treetype[i] << "\r\n"; StringStream ss; Store(callback(this, &Pdb::SerializeSession), ss); WorkspaceConfigData("pdb-debugger") = ss; if(hProcess == INVALID_HANDLE_VALUE) { LOG("hProcess Handle is invalid handle value");}; if(hProcess != INVALID_HANDLE_VALUE) { LOG("DebugActiveProcessStop"); for(int i=0; i<10; i++){ if (retval = DebugActiveProcessStop(processid)) break; DUMPHEX(retval); Sleep(100); } DUMPHEX(retval); retval = TerminateProcess(hProcess, 0); LOG("TerminateProcess"); DUMPHEX(retval); retval = WaitForSingleObject(hProcess,10000); LOG("WaitForSingleObject"); DUMPHEX(retval); #ifdef NEVEREVER retval = MsgWaitForMultipleObjects( 1, //DWORD nCount, &hProcess, //const HANDLE *pHandles, true, //BOOL fWaitAll, 10000, //DWORD dwMilliseconds, 0 //DWORD dwWakeMask ); LOG("WaitForMultibleObjects"); DUMPHEX(retval); #endif while(threads.GetCount()) RemoveThread(threads.GetKey(0)); // To CloseHandle UnloadModuleSymbols(); SymCleanup(hProcess); retval = CloseHandle(hProcess); LOG("CloseHandle"); DUMPHEX(retval); } StoreToGlobal(*this, CONFIGNAME); IdeRemoveBottom(*this); IdeRemoveRight(disas); } }
--------------------------------------- terminated flag terminated = false DebugActiveProcessStop retval = 0x0 retval = 0x1 TerminateProcess retval = 0x0 WaitForSingleObject retval = 0x0 CloseHandle retval = 0x1
Tired of this, I added TerminateChildProcesses() just before TerminateProcess().
One week, no problem
Now, if it happens only once a week this should not be a problem.
When I had the problem, it happened again and again.
I debugged simple programs without child processes.
And after the latest modification (DebugProcessStop) I had not a single problem and I did heavy repeated testing and I tried to provoke the problem.
It did not happen again here.
All the best, and happy new year!
Now, if it happens only once a week this should not be a problem.Yes I agree.
When I had the problem, it happened again and again.
I debugged simple programs without child processes.
And after the latest modification (DebugProcessStop) I had not a single problem and I did heavy repeated testing and I tried to provoke the problem.
It did not happen again here.
hProcess = pi.hProcess; hProcessId = pi.dwProcessId; // Added mainThread = pi.hThread; mainThreadId = pi.dwThreadId;
#include <TlHelp32.h> Vector<DWORD> GetChildProcessList(DWORD processId) { Vector<DWORD> child, all, parents; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE) return child; PROCESSENTRY32 proc; proc.dwSize = sizeof(proc); if (!Process32First(hSnap, &proc)) { CloseHandle(hSnap); return child; } do { all << proc.th32ProcessID; parents << proc.th32ParentProcessID; } while(Process32Next(hSnap, &proc)); CloseHandle(hSnap); child << processId; int init = 0; while (true) { int count = child.GetCount(); if (init >= count) break; for (int cid = init; cid < count; ++cid) { for (int i = 0; i < all.GetCount(); ++i) { if (parents[i] == child[cid]) child << all[i]; } } init = count; } child.Remove(0); return child; } void TerminateChildProcesses(DWORD dwProcessId, UINT uExitCode) { Vector<DWORD> children = GetChildProcessList(dwProcessId); for (int i = 0; i < children.GetCount(); ++i) { HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, children[i]); TerminateProcess(hProcess, uExitCode); CloseHandle(hProcess); } }
One week, no problem :)Other week, no problem ]]>