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
This commit is contained in:
cxl 2019-11-29 13:51:32 +00:00
parent 25719a9282
commit 44ebb07a26
6 changed files with 84 additions and 21 deletions

View file

@ -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)

View file

@ -114,6 +114,8 @@ struct Pdb : Debugger, ParentCtrl {
struct NamedVal : Moveable<NamedVal> {
String name;
Val val;
Val key;
int64 from = 0;
};
struct Type : Moveable<Type> {
@ -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);

View file

@ -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

View file

@ -75,7 +75,7 @@ Array<Pdb::Frame> 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 << ')';
}

View file

@ -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<Val> 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<NamedVal>(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);

View file

@ -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 {