From 44ebb07a26cae9a6f4ccd0057ba52b973d535942 Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 29 Nov 2019 13:51:32 +0000 Subject: [PATCH] ide: PDB debugger now supports tree view of recognized high-level types git-svn-id: svn://ultimatepp.org/upp/trunk@13724 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ide/Debuggers/Data.cpp | 1 + uppsrc/ide/Debuggers/Pdb.h | 7 ++- uppsrc/ide/Debuggers/Pretty.cpp | 5 ++ uppsrc/ide/Debuggers/Stack.cpp | 2 +- uppsrc/ide/Debuggers/Tree.cpp | 84 ++++++++++++++++++++++++------ uppsrc/ide/Debuggers/Visualise.cpp | 6 +-- 6 files changed, 84 insertions(+), 21 deletions(-) diff --git a/uppsrc/ide/Debuggers/Data.cpp b/uppsrc/ide/Debuggers/Data.cpp index 84539faaa..21d2794d1 100644 --- a/uppsrc/ide/Debuggers/Data.cpp +++ b/uppsrc/ide/Debuggers/Data.cpp @@ -308,6 +308,7 @@ void Pdb::Data() case TAB_EXPLORER: Explorer(); break; case TAB_MEMORY: memory.Refresh(); break; } + SetTree(tree_exp); } void Pdb::MemoryGoto(const String& exp) diff --git a/uppsrc/ide/Debuggers/Pdb.h b/uppsrc/ide/Debuggers/Pdb.h index 818dedb36..00cc9071c 100644 --- a/uppsrc/ide/Debuggers/Pdb.h +++ b/uppsrc/ide/Debuggers/Pdb.h @@ -114,6 +114,8 @@ struct Pdb : Debugger, ParentCtrl { struct NamedVal : Moveable { String name; Val val; + Val key; + int64 from = 0; }; struct Type : Moveable { @@ -382,8 +384,8 @@ struct Pdb : Debugger, ParentCtrl { enum { MEMBER = 1, RAW = 2 }; void BaseFields(Visual& result, const Type& t, Pdb::Val val, dword flags, bool& cm, int depth); void Visualise(Visual& result, Pdb::Val val, dword flags); - Visual Visualise(Val v); - Visual Visualise(const String& rexp); + Visual Visualise(Val v, dword flags = 0); + Visual Visualise(const String& rexp, dword flags = 0); bool VisualisePretty(Visual& result, Pdb::Val val, dword flags); @@ -465,6 +467,7 @@ struct Pdb : Debugger, ParentCtrl { void SetTree(const String& exp); void SetTreeA(ArrayCtrl *data); + void PrettyTreeNode(int parent, Pdb::Val val, int64 from = 0); void TreeNode(int parent, const String& name, Val val); void TreeExpand(int node); String StoreTree(int parent); diff --git a/uppsrc/ide/Debuggers/Pretty.cpp b/uppsrc/ide/Debuggers/Pretty.cpp index 469af368d..2c44ad537 100644 --- a/uppsrc/ide/Debuggers/Pretty.cpp +++ b/uppsrc/ide/Debuggers/Pretty.cpp @@ -228,6 +228,11 @@ Pdb::Val Pdb::MakeVal(const String& type, adr_t address) bool Pdb::PrettyVal(Pdb::Val val, int64 from, int count, Pretty& p) { + ASSERT(count < 100000); + + if(val.type < 0) + return false; + const Type& t = GetType(val.type); current_modbase = t.modbase; // so that we do not need to pass it as parameter in Pretty routines diff --git a/uppsrc/ide/Debuggers/Stack.cpp b/uppsrc/ide/Debuggers/Stack.cpp index 903357473..6ecc82e57 100644 --- a/uppsrc/ide/Debuggers/Stack.cpp +++ b/uppsrc/ide/Debuggers/Stack.cpp @@ -75,7 +75,7 @@ Array Pdb::Backtrace(Thread& ctx, bool single_frame) for(int i = 0; i < f.param.GetCount(); i++) { if(i) f.text << ", "; - f.text << f.param.GetKey(i) << "=" << Visualise(f.param[i]).GetString(); + f.text << f.param.GetKey(i) << "=" << Visualise(f.param[i], MEMBER).GetString(); } f.text << ')'; } diff --git a/uppsrc/ide/Debuggers/Tree.cpp b/uppsrc/ide/Debuggers/Tree.cpp index a5e3fb253..04902da8d 100644 --- a/uppsrc/ide/Debuggers/Tree.cpp +++ b/uppsrc/ide/Debuggers/Tree.cpp @@ -4,8 +4,67 @@ #define LLOG(x) // LOG(x) +void Pdb::PrettyTreeNode(int parent, Pdb::Val val, int64 from) +{ + try { + Pretty pp; + if(PrettyVal(val, 0, 0, pp) && pp.kind == CONTAINER) { + int n = int(min(pp.data_count, from + 10000) - from); + Pretty p; + PrettyVal(val, from, n, p); + + if(p.data_type.GetCount()) { + Buffer item(p.data_type.GetCount()); + for(int i = 0; i < p.data_type.GetCount(); i++) { + (TypeInfo &)item[i] = GetTypeInfo(p.data_type[i]); + item[i].context = val.context; + } + int ii = 0; + int n = p.data_ptr.GetCount() / p.data_type.GetCount(); + for(int i = 0; i < n; i++) { + NamedVal nv; + nv.name << '[' << i + from << ']'; + nv.val = val; + Visual result; + try { + for(int j = 0; j < p.data_type.GetCount(); j++) { + if(j) + result.Cat(": "); + item[j].address = p.data_ptr[ii++]; + nv.val = item[j]; + if(p.data_type.GetCount() > 1 && j == 0) + nv.key = item[0]; + Visualise(result, item[j], 0); + } + } + catch(LengthLimit) {} + catch(CParser::Error e) { + result.Cat("??"); + } + tree.Add(parent, Null, RawToValue(nv), nv.name + ' ' + result.GetString(), + nv.key.type != UNKNOWN || nv.val.type > 0); + } + if(pp.data_count > n && from == 0) { + NamedVal nv; + nv.name << ".."; + nv.val = val; + int64 ii = n; + while(ii < pp.data_count) { + nv.from = ii; + tree.Add(parent, Null, RawToValue(nv), String() << "[" << ii << ".." << min(pp.data_count - 1, ii + 9999) << "]", true); + ii += 10000; + } + } + } + } + } + catch(LengthLimit) {} + catch(CParser::Error e) {} +} + void Pdb::TreeNode(int parent, const String& name, Pdb::Val val) { + PrettyTreeNode(parent, val); NamedVal nv; nv.name = name; nv.val = val; @@ -21,6 +80,15 @@ void Pdb::TreeExpand(int node) return; const NamedVal& nv = ValueTo(tree.Get(node)); Val val = nv.val; + if(nv.key.type != UNKNOWN) { + TreeNode(node, "key", nv.key); + TreeNode(node, "value", val); + return; + } + if(nv.from > 0) { + PrettyTreeNode(node, val, nv.from); + return; + } if(nv.val.ref > 0) { val = DeRef(val); if(val.type < 0 || val.ref > 0) { @@ -57,21 +125,6 @@ void Pdb::TreeExpand(int node) vtbl.address = val.address + t.vtbl_offset; vtbl.type = t.vtbl_typeindex; TreeNode(node, "virtual", vtbl); -/* - Val vloc = GetRVal(vtbl); - FnInfo vtbl_type = GetFnInfo(vloc.address); - const char *p = vtbl_type.name, *e = p; - while(*e && !(*e == ':' && e[1] == ':')) - e++; - String fullsym(p, e); - FnInfo ffs = GetFnInfo(fullsym); - if(ffs.pdbtype) { - Val typeval; - typeval.address = val.address; - TypeVal(typeval, ffs.pdbtype, t.modbase); - TreeNode(node, String().Cat() << '[' << ffs.name << ']', typeval); - } -*/ } for(int i = 0; i < t.base.GetCount(); i++) { Val r = t.base[i]; @@ -191,6 +244,7 @@ void Pdb::SetTree(const String& exp) if(nv.val.type >= 0) n = GetType(nv.val.type).name; tree.SetRoot(Null, RawToValue(nv), n + '=' + Visualise(nv.val).GetString()); + PrettyTreeNode(0, nv.val); if(nv.val.type >= 0) { String w = treetype.Get(n, Null); LOG("SetTree " << n << ' ' << w); diff --git a/uppsrc/ide/Debuggers/Visualise.cpp b/uppsrc/ide/Debuggers/Visualise.cpp index f139ef64d..99528e3d5 100644 --- a/uppsrc/ide/Debuggers/Visualise.cpp +++ b/uppsrc/ide/Debuggers/Visualise.cpp @@ -9,7 +9,7 @@ void Pdb::Visual::Cat(const String& text, Color ink) p.ink = ink; p.mark = false; length += text.GetLength(); - if(length > 250) + if(length > 500) throw LengthLimit(); } @@ -298,7 +298,7 @@ Size Pdb::Visual::GetSize() const return Size(cx, StdFont().Info().GetHeight()); } -Pdb::Visual Pdb::Visualise(Val v) +Pdb::Visual Pdb::Visualise(Val v, dword flags) { Visual r; try { @@ -311,7 +311,7 @@ Pdb::Visual Pdb::Visualise(Val v) return r; } -Pdb::Visual Pdb::Visualise(const String& exp) +Pdb::Visual Pdb::Visualise(const String& exp, dword flags) { Visual r; try {