From a511e3a67beb232c3f069861690f9fa96fffd64a Mon Sep 17 00:00:00 2001 From: cxl Date: Wed, 21 Mar 2018 21:35:17 +0000 Subject: [PATCH] Debugger improvements git-svn-id: svn://ultimatepp.org/upp/trunk@11857 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ide/Debuggers/Debuggers.h | 1 + uppsrc/ide/Debuggers/Gdb.cpp | 97 ++++++++++++++++++++++---------- uppsrc/ide/Debuggers/GdbCmd.cpp | 1 - 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/uppsrc/ide/Debuggers/Debuggers.h b/uppsrc/ide/Debuggers/Debuggers.h index a5f82f3b6..c36fabb1a 100644 --- a/uppsrc/ide/Debuggers/Debuggers.h +++ b/uppsrc/ide/Debuggers/Debuggers.h @@ -203,6 +203,7 @@ public: void TreeExpand(int node); void CopyStack(); + void CopyStackAll(); void CopyDisas(); bool Create(One&& host, const String& exefile, const String& cmdline, bool console); diff --git a/uppsrc/ide/Debuggers/Gdb.cpp b/uppsrc/ide/Debuggers/Gdb.cpp index 2e0d0ccbe..22ee3d493 100644 --- a/uppsrc/ide/Debuggers/Gdb.cpp +++ b/uppsrc/ide/Debuggers/Gdb.cpp @@ -27,9 +27,41 @@ void Gdb::DebugBar(Bar& bar) bar.Add(b, AK_CPU, THISBACK1(SetTab, 4)); bar.MenuSeparator(); bar.Add(b, "Copy backtrace", THISBACK(CopyStack)); + bar.Add(b, "Copy backtrace of all threads", THISBACK(CopyStackAll)); bar.Add(b, "Copy dissassembly", THISBACK(CopyDisas)); } +String FormatFrame(const char *s) +{ + if(*s++ != '#') + return Null; + while(IsDigit(*s)) + s++; + while(*s == ' ') + s++; + if(s[0] == '0' && ToUpper(s[1]) == 'X') { + s += 2; + while(IsXDigit(*s)) + s++; + while(*s == ' ') + s++; + if(s[0] != 'i' && s[1] != 'n') + return Null; + s += 2; + while(*s == ' ') + s++; + } + if(!IsAlpha(*s)) + return Null; + const char *w = strchr(s, '\r'); + if(w) + return String(s, w); + w = strchr(s, '\n'); + if(w) + return String(s, w); + return s; +} + void Gdb::CopyStack() { if(IdeIsDebugLock()) @@ -41,6 +73,40 @@ void Gdb::CopyStack() WriteClipboardText(s); } +void Gdb::CopyStackAll() +{ + String s = FastCmd("info threads"); + StringStream ss(s); + String r; + while(!ss.IsEof()) { + String s = ss.GetLine(); + CParser p(s); + try { + bool active = p.Char('*'); + if(p.IsNumber()) { + int id = p.ReadInt(); + r << "----------------------------------\r\n" + << "Thread: " << id << "\r\n\r\n"; + + FastCmd(Sprintf("thread %d", id)); + + int i = 0; + int q = ~frame; + frame.Clear(); + for(;;) { + String s = FormatFrame(FastCmd("frame " + AsString(i++))); + if(IsNull(s)) break; + r << s << "\r\n"; + } + r << "\r\n"; + } + } + catch(CParser::Error) {} + } + FastCmd(Sprintf("thread %d", ~threads)); + WriteClipboardText(r); +} + void Gdb::CopyDisas() { if(IdeIsDebugLock()) @@ -116,37 +182,6 @@ void Gdb::SyncDisas(bool fr) disas.SetIp(addr, fr ? DbgImg::FrameLinePtr() : DbgImg::IpLinePtr()); } -String FormatFrame(const char *s) -{ - if(*s++ != '#') - return Null; - while(IsDigit(*s)) - s++; - while(*s == ' ') - s++; - if(s[0] == '0' && ToUpper(s[1]) == 'X') { - s += 2; - while(IsXDigit(*s)) - s++; - while(*s == ' ') - s++; - if(s[0] != 'i' && s[1] != 'n') - return Null; - s += 2; - while(*s == ' ') - s++; - } - if(!IsAlpha(*s)) - return Null; - const char *w = strchr(s, '\r'); - if(w) - return String(s, w); - w = strchr(s, '\n'); - if(w) - return String(s, w); - return s; -} - bool ParsePos(const String& s, String& fn, int& line, adr_t & adr) { const char *q = FindTag(s, "\x1a\x1a"); diff --git a/uppsrc/ide/Debuggers/GdbCmd.cpp b/uppsrc/ide/Debuggers/GdbCmd.cpp index 995683df9..a96eaf007 100644 --- a/uppsrc/ide/Debuggers/GdbCmd.cpp +++ b/uppsrc/ide/Debuggers/GdbCmd.cpp @@ -152,7 +152,6 @@ String Gdb::FastCmd(const char *command) if(!dbg || !dbg->IsRunning() || IdeIsDebugLock()) return Null; bool lock = false; if(command) { - LLOG("FastCmd: " << command); dbg->Write(String(command) + "\n"); PutVerbose(command); }