mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
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:
parent
25719a9282
commit
44ebb07a26
6 changed files with 84 additions and 21 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 << ')';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue