Ide/Debuggers /Gdb_MI2 : added asynchronous break command

git-svn-id: svn://ultimatepp.org/upp/trunk@4872 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
micio 2012-04-28 20:00:32 +00:00
parent aeae11c11d
commit 45f652c44e
2 changed files with 36 additions and 3 deletions

View file

@ -10,6 +10,7 @@ void Gdb_MI2::DebugBar(Bar& bar)
{
bar.Add("Stop debugging", THISBACK(Stop)).Key(K_SHIFT_F5);
bar.Separator();
bar.Add("Asynchronous break", THISBACK(AsyncBrk));
bool b = !IdeIsDebugLock();
bar.Add(b, "Step into", DbgImg::StepInto(), THISBACK1(Step, disas.HasFocus() ? "exec-step-instruction" : "exec-step")).Key(K_F11);
bar.Add(b, "Step over", DbgImg::StepOver(), THISBACK1(Step, disas.HasFocus() ? "exec-next-instruction" : "exec-next")).Key(K_F10);
@ -115,6 +116,24 @@ void Gdb_MI2::Run()
IdeActivateBottom();
}
void Gdb_MI2::AsyncBrk()
{
// send an interrupt command to all running threads
MICmd("exec-interrupt --all");
// gdb usually returns to command prompt instantly, BEFORE
// giving out stop reason, which we need. So, we wait some
// milliseconds and re-read (non blocking) GDB output to get it
for(int i = 0; i < 20 && !stopped; i++)
{
Sleep(100);
ReadGdb(false);
}
// if target is correctly stopped, 'stopped' flag should be already set
// so we don't care here. If not set, target can't be stopped.
}
void Gdb_MI2::Stop()
{
stopped = true;
@ -489,7 +508,7 @@ MIValue Gdb_MI2::MICmd(const char *cmdLine)
// sends command to debugger and get result data
// should handle dbg unexpected termination ?
if(!dbg || !dbg->IsRunning() || IdeIsDebugLock())
if(!dbg || !dbg->IsRunning() /* || IdeIsDebugLock() */)
return MIValue();
// consume previous output from gdb... don't know why sometimes
@ -684,8 +703,11 @@ void Gdb_MI2::LogFrame(String const &msg, MIValue &frame)
// check for stop reason
void Gdb_MI2::CheckStopReason(void)
{
ASSERT(!stopReason.IsEmpty());
String reason = stopReason["reason"];
String reason;
if(stopReason.IsEmpty())
reason = "unknown reason";
else
reason = stopReason["reason"];
if(reason == "exited-normally")
{
Stop();
@ -701,6 +723,10 @@ void Gdb_MI2::CheckStopReason(void)
LogFrame("Hit breakpoint", stopReason["frame"]);
SyncIde();
}
else if(reason == "unknown reason")
{
PutConsole("Stopped by unknown reason");
}
else
{
LogFrame(Format("Stopped, reason '%s'", reason), stopReason["frame"]);
@ -1473,6 +1499,12 @@ bool Gdb_MI2::Create(One<Host> _host, const String& exefile, const String& cmdli
watches.WhenAcceptEdit = THISBACK(SyncData);
tab <<= THISBACK(SyncData);
// this one will allow asynchronous break of running app
MICmd("gdb-set target-async 1");
MICmd("gdb-set pagination off");
MICmd("gdb-set non-stop on");
// MICmd("gdb-set interactive-mode off");
MICmd("gdb-set disassembly-flavor intel");
MICmd("gdb-set exec-done-display off");
MICmd("gdb-set annotate 1");

View file

@ -216,6 +216,7 @@ class Gdb_MI2 : public Debugger, public ParentCtrl
// debugger IDE inteface
virtual void DebugBar(Bar& bar);
virtual bool SetBreakpoint(const String& filename, int line, const String& bp);
virtual void AsyncBrk();
virtual bool RunTo();
virtual void Run();
virtual void Stop();