diff --git a/uppsrc/ide/Debuggers/Gdb_MI2.cpp b/uppsrc/ide/Debuggers/Gdb_MI2.cpp index 4a5ebe8ac..978adac94 100644 --- a/uppsrc/ide/Debuggers/Gdb_MI2.cpp +++ b/uppsrc/ide/Debuggers/Gdb_MI2.cpp @@ -550,9 +550,19 @@ void Gdb_MI2::SyncDisas(MIValue &fInfo, bool fr) adr_t adr = stou(~fInfo["addr"].Get().Mid(2), NULL, 16); if(!disas.InRange(adr)) { - String file = fInfo["file"]; - String line = fInfo["line"]; - MIValue code = MICmd(Format("data-disassemble -f %s -l %s -n -1 -- 0", file, line))["asm_insns"]; + MIValue code; + + // if frame is inside a source file, disassemble current function + if(fInfo.Find("file") >= 0 && fInfo.Find("line") >= 0) + { + String file = fInfo["file"]; + String line = fInfo["line"]; + code = MICmd(Format("data-disassemble -f %s -l %s -n -1 -- 0", file, line))["asm_insns"]; + } + else + // otherwise disassemble some -100 ... +100 bytes around address + code = MICmd(Format("data-disassemble -s %x -e %x -- 0", (void *)(adr - 100), (void *)(adr + 100)))["asm_insns"]; + disas.Clear(); for(int iLine = 0; iLine < code.GetCount(); iLine++) { @@ -606,6 +616,17 @@ void Gdb_MI2::SyncIde(bool fr) SyncDisas(fInfo, fr); } +// logs frame data on console +void Gdb_MI2::LogFrame(String const &msg, MIValue &frame) +{ + String file = frame("file", ""); + String line = frame("line", ""); + String function = frame("function", ""); + String addr = frame("addr", ""); + + PutConsole(Format(msg + " at %s, function '%s', file '%s', line %s", addr, function, file, line)); +} + // check for stop reason void Gdb_MI2::CheckStopReason(void) { @@ -623,22 +644,12 @@ void Gdb_MI2::CheckStopReason(void) } else if(reason == "breakpoint-hit") { - MIValue &v = stopReason["frame"]; - String file = v["file"]; - String line = v["line"]; - String function = v["func"]; - String addr = v["addr"]; - PutConsole(Format("Hit breakpoint at %s, function '%s', file '%s', line %s", addr, function, file, line)); + LogFrame("Hit breakpoint", stopReason["frame"]); SyncIde(); } else { - MIValue &v = stopReason["frame"]; - String file = v["file"]; - String line = v["line"]; - String function = v["func"]; - String addr = v["addr"]; - PutConsole(Format("Stopped at %s, function '%s', file '%s', line %s, reason '%s'", addr, function, file, line, stopReason["reason"].Get())); + LogFrame(Format("Stopped, reason '%s'", reason), stopReason["frame"]); SyncIde(); } } @@ -707,9 +718,9 @@ void Gdb_MI2::DisasFocus() String Gdb_MI2::FormatFrame(MIValue &fInfo, MIValue &fArgs) { int idx = atoi(fInfo["level"].Get()); - String func = fInfo["func"]; - String file = fInfo["file"]; - String line = fInfo["line"]; + String func = fInfo("func", ""); + String file = fInfo("file", ""); + String line = fInfo("line", ""); int nArgs = fArgs.GetCount(); String argLine; for(int iArg = 0; iArg < nArgs; iArg++) diff --git a/uppsrc/ide/Debuggers/Gdb_MI2.h b/uppsrc/ide/Debuggers/Gdb_MI2.h index f51348f88..15912730c 100644 --- a/uppsrc/ide/Debuggers/Gdb_MI2.h +++ b/uppsrc/ide/Debuggers/Gdb_MI2.h @@ -76,6 +76,9 @@ class Gdb_MI2 : public Debugger, public ParentCtrl // update local variables on demand void UpdateLocalVars(void); + // logs frame data on console + void LogFrame(String const &msg, MIValue &frame); + // check for stop reason void CheckStopReason(void); diff --git a/uppsrc/ide/Debuggers/MIValue.cpp b/uppsrc/ide/Debuggers/MIValue.cpp index 31e27ccf3..a9ac54a99 100644 --- a/uppsrc/ide/Debuggers/MIValue.cpp +++ b/uppsrc/ide/Debuggers/MIValue.cpp @@ -261,6 +261,20 @@ String const &MIValue::Get(void) const return string; } +// tuple string member accessor with default value if not found +String MIValue::Get(const char *key, const char *def) const +{ + ASSERT(type == MITuple); + int i = tuple.Find(key); + if(i >= 0) + { + ASSERT(tuple[i].type == MIString); + return tuple[i]; + } + else + return def; +} + // data dump String MIValue::Dump(int level) { diff --git a/uppsrc/ide/Debuggers/MIValue.h b/uppsrc/ide/Debuggers/MIValue.h index d23aa55ef..b0aa869ec 100644 --- a/uppsrc/ide/Debuggers/MIValue.h +++ b/uppsrc/ide/Debuggers/MIValue.h @@ -53,7 +53,10 @@ class MIValue : public Moveable operator const String &() const { return Get(); } String &ToString(void) { return Get(); } String const &ToString(void) const { return Get(); } -// operator const char *() { return Get(); } + + // tuple string member accessor with default value if not found + String Get(const char *key, const char *def) const; + String operator()(const char *key, const char *def) const { return Get(key, def); } // some type checking bool IsArray(void) { return type == MIArray; }