C::b is open source so: look into the code ;)
int CompilerGCC::KillProcess()
{
ResetBuildState();
m_RunAfterCompile = false;
if (!IsProcessRunning())
return 0;
if (!m_CommandQueue.LastCommandWasRun())
LogMessage(_("Aborting build..."), cltInfo, ltMessages);
wxKillError ret = wxKILL_OK;
m_CommandQueue.Clear();
for (size_t i = 0; i < m_CompilerProcessList.size(); ++i)
{
if (!m_CompilerProcessList.at(i).pProcess)
continue;
#if defined(WIN32) && defined(ENABLE_SIGTERM)
::GenerateConsoleCtrlEvent(0, m_CompilerProcessList.at(i).PID);
#endif
// Close input pipe
m_CompilerProcessList.at(i).pProcess->CloseOutput();
((PipedProcess*) m_CompilerProcessList.at(i).pProcess)->ForfeitStreams();
ret = wxProcess::Kill(m_CompilerProcessList.at(i).PID, wxSIGTERM);
if (!platform::windows)
{
if (ret != wxKILL_OK)
{
// No need to tell the user about the errors - just keep him waiting.
Manager::Get()->GetLogManager()->Log(F(_("Aborting process %d ..."), i), m_PageIndex);
}
else switch (ret)
{
case wxKILL_OK:
Manager::Get()->GetLogManager()->Log(_("Process aborted (killed)."), m_PageIndex);
// case wxKILL_ACCESS_DENIED: cbMessageBox(_("Access denied")); break;
// case wxKILL_NO_PROCESS: cbMessageBox(_("No process")); break;
// case wxKILL_BAD_SIGNAL: cbMessageBox(_("Bad signal")); break;
// case wxKILL_ERROR: cbMessageBox(_("Unspecified error")); break;
case wxKILL_ACCESS_DENIED: // fall-through
case wxKILL_NO_PROCESS: // fall-through
case wxKILL_BAD_SIGNAL: // fall-through
case wxKILL_ERROR: // fall-through
default: break;
}
}
}
ProjectManager *projectManager = Manager::Get()->GetProjectManager();
if (projectManager->GetIsRunning() == this)
projectManager->SetIsRunning(NULL);
return ret;
}
ret = wxProcess::Kill(m_CompilerProcessList.at(i).PID, wxSIGTERM);
Wouldn't that be the same than using taskkill PID on the console? This produces a different result that that button, so the button must do sth else.
C::b is open source so: look into the code ;)
Forgot to say that I tried that. Unfortunately CB does not compile so I can't use a breakpoint to find out where I need to look or what I need to search for. Unfortunatley I did not yet understand the structure of the source, though. Maybe a hint about which class handles that button would help.
Very helpful answer, thanks.
After the initial surprise about the huge number of Abort hits I managed to find the location. Great. The killing is just a few lines, just as posted. However its helpful to see the bits around as well.
I am not sure what the purpose of that event is, does that influence the Kill below?
#if defined(WIN32) && defined(ENABLE_SIGTERM)
::GenerateConsoleCtrlEvent(0, m_CompilerProcessList.at(i).PID);
#endif
Basically that kill command in here
// Close input pipe
m_CompilerProcessList.at(i).pProcess->CloseOutput();
((PipedProcess*) m_CompilerProcessList.at(i).pProcess)->ForfeitStreams();
ret = wxProcess::Kill(m_CompilerProcessList.at(i).PID, wxSIGTERM);
should be doing the same as
taskkill /F /IM MyApp.exe
shouldn't it? But it does not and I can not see why. The code kill takes the app to hang for 1-2 secs before the Program stopped error is displayed. The console kill closes it instantly.
After the crash I get this output of Dr. MinGw. The only codeline from my app is IMPLEMENT_APP().
Test.exe caused an Access Violation at location 6fe718d0 in module libstdc++-6.dll Reading from location 000000c8.
Registers:
eax=000000c4 ebx=00000000 ecx=000000c4 edx=00000000 esi=00000000 edi=0000003c
eip=6fe718d0 esp=0028fa9c ebp=0028fab8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
Call stack:
6FE718D0 libstdc++-6.dll:6FE718D0 _ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5emptyEv
61D829F7 wxmsw293ud_gcc_custom.dll:61D829F7 _ZNK16wxAppConsoleBase17GetAppDisplayNameEv
61FD5F27 wxmsw293ud_gcc_custom.dll:61FD5F27 _ZNK8wxLogGui8GetTitleEv
61FD61DB wxmsw293ud_gcc_custom.dll:61FD61DB _ZN8wxLogGui5FlushEv
61DD6339 wxmsw293ud_gcc_custom.dll:61DD6339 _ZN5wxLog15SetActiveTargetEPS_
61DCBADD wxmsw293ud_gcc_custom.dll:61DCBADD _Z12wxEntryStartRiPPc
61DCBB48 wxmsw293ud_gcc_custom.dll:61DCBB48 _Z14wxEntryCleanupv
61DCBDE0 wxmsw293ud_gcc_custom.dll:61DCBDE0 _Z14wxUninitializev
623B5BE4 wxmsw293ud_gcc_custom.dll:623B5BE4 _ZN13wxInitializerD1Ev
61DCBC0D wxmsw293ud_gcc_custom.dll:61DCBC0D _Z11wxEntryRealRiPPw
61E49D74 wxmsw293ud_gcc_custom.dll:61E49D74 _Z7wxEntryRiPPw
61E4A062 wxmsw293ud_gcc_custom.dll:61E4A062 _Z7wxEntryP11HINSTANCE__S0_Pci
00443FB7 Test.exe:00443FB7 WinMain@16 Test.cpp:30
int32 WinMain@16(
HINSTANCE hInstance = &{
int32 unused = 9460301
},
HINSTANCE hPrevInstance = &{
int32 unused =
},
int32 nCmdShow = 10
)
...
//////////////////////////////////////////////////////////////////////
// 2010-03-08
> IMPLEMENT_APP(CTestApp)
...
005026CD Test.exe:005026CD operator+ gdicmn.h:560
struct wxPoint operator+(
struct wxPoint * p1 = &{
int32 x = 12529593,
int32 y = 0
},
struct wxPoint * p2 = &{
int32 x = ,
int32 y =
}
)
...
{
return wxPoint(p1.x + p2.x, p1.y + p2.y);
> }
inline wxPoint operator-(const wxPoint& p1, const wxPoint& p2)
...
004013E2 Test.exe:004013E2
768F33CA kernel32.dll:768F33CA BaseThreadInitThunk
76F49ED2 ntdll.dll:76F49ED2 RtlInitializeExceptionChain
76F49EA5 ntdll.dll:76F49EA5 RtlInitializeExceptionChain
Tiger
PS interesting side detail in the code, why are you collecing all plugin events in a dispatcher. I can not really see the advantage not to list the functions in the event table?