void Gdb_MI2::Run() { MIValue val; if(firstRun) val = MICmd("exec-run"); else val = MICmd("exec-continue --all"); int i = 50; while(!started && --i) { GuiSleep(20); Ctrl::ProcessEvents(); ReadGdb(false); } if(!started) { Exclamation(t_("Failed to start application")); IdeEndDebug(); return; } Lock(); while(dbg && !stopped) { GuiSleep(20); Ctrl::ProcessEvents(); ReadGdb(false); } Unlock(); if(stopped) CheckStopReason(); started = stopped = false; firstRun = false; IdeActivateBottom(); }
// THREAD INFO INSIDE RESPONSES // id The numeric id assigned to the thread by gdb. This field is always present. // target-id Target-specific string identifying the thread. This field is always present. // details Additional information about the thread provided by the target. It is supposed to be human-readable and not interpreted by the frontend. This field is optional. // state Either `stopped' or `running', depending on whether the thread is presently running. This field is always present. // core The value of this field is an integer number of the processor core the thread was last seen on. This field is optional. // // REMARKS : by now, we just handle synchronous output and check asynchronous one just to detect // debugger run/stop status -- all remaining asynchrnonous output is discarded MIValue Gdb_MI2::MICmd(const char *cmdLine) { MIValue res; #ifdef flagMT // on MT, we interrupt all non-main threads // issued GDB commands (which normally can lag several seconds...) // before issuing the command if(IsMainThread() && IsThreadRunning()) ShutDownThreads(); // quick exit for service thread if(!IsMainThread() && IsStopThread()) throw BreakExc(); // lock other thread's access INTERLOCKED { #endif // sends command to debugger and get result data // should handle dbg unexpected termination ? if(!dbg || !dbg->IsRunning() /* || IdeIsDebugLock() */) return MIValue(); // consume previous output from gdb... don't know why sometimes // is there and gives problems to MI interface. We shall maybe // parse and store it somewhere ReadGdb(false); dbg->Write(String("-") + cmdLine + "\n"); res = ReadGdb(); #ifdef flagMT } #endif return res; }
void Gdb_MI2::AsyncBrk() { #ifdef PLATFORM_POSIX // send interrupt command to debugger if(!InterruptDebugger()) return; // if successful, wait for some time for 'stopped' flag to become true for(int iMsec = 0; iMsec < 1000; iMsec += 20) { ReadGdb(false); Sleep(20); Ctrl::ProcessEvents(); if(stopped) break; } #endif }