ide: GDB gui now has memory tab

git-svn-id: svn://ultimatepp.org/upp/trunk@13501 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2019-07-19 12:16:13 +00:00
parent 090e1839ca
commit b92b70807d
8 changed files with 153 additions and 37 deletions

View file

@ -52,7 +52,7 @@ void HexViewInfo::Paint(Draw& w)
{
Size sz = GetSize();
w.DrawRect(sz, SColorLtFace);
if(mode < 1)
if(mode < 1 || empty)
return;
Size fsz = GetTextSize("X", font);
char h[17];
@ -149,11 +149,15 @@ void HexView::Paint(Draw& w)
{
Size sz = GetSize();
w.DrawRect(sz, SColorPaper);
if(!total) {
w.DrawText(Zx(10), Zx(10), "No data", ArialZ(20).Italic(), SRed());
return;
}
int y = 0;
int64 adr = sc;
uint64 adr = sc;
while(y < sz.cy) {
char h[17];
FormatHex(h, adr, IsLongMode() ? 16 : 8);
FormatHex(h, adr + start, IsLongMode() ? 16 : 8);
w.DrawText(0, y, h, font);
int x = (IsLongMode() ? 17 : 9) * fsz.cx;
int tx = x + columns * fcx3;
@ -212,9 +216,10 @@ void HexView::MouseWheel(Point, int zdelta, dword)
void HexView::SetSb()
{
sbm = 0;
while((total >> sbm) > (1 << 30))
uint64 sz = total;
while((sz >> sbm) > (1 << 30))
sbm++;
sb.SetTotal(int(total >> sbm) / columns + 2);
sb.SetTotal(int(sz >> sbm) / columns + 2);
sb.SetPage(int(rows >> sbm));
sb.Set(int(sc >> sbm) / columns + 1);
}
@ -228,7 +233,16 @@ void HexView::Layout()
SetSb();
}
void HexView::SetTotal(int64 _total)
void HexView::SetStart(uint64 start_)
{
start = start_;
Layout();
SetSb();
Refresh();
RefreshInfo();
}
void HexView::SetTotal(uint64 _total)
{
total = _total;
Layout();
@ -237,9 +251,9 @@ void HexView::SetTotal(int64 _total)
RefreshInfo();
}
void HexView::SetSc(int64 address)
void HexView::SetSc(uint64 address)
{
sc = minmax(address, (int64)0, total);
sc = minmax(address, start, total);
SetSb();
Refresh();
}
@ -256,14 +270,19 @@ void HexView::Scroll()
void HexView::RefreshInfo()
{
info.SetPos(cursor, IsLongMode());
for(int i = 0; i < 80; i++)
info.Set(i, Byte(cursor + i));
if(total) {
info.SetPos(cursor + start, IsLongMode());
for(int i = 0; i < 80; i++)
info.Set(i, Byte(cursor + i));
}
else
info.SetEmpty();
}
void HexView::SetCursor(int64 _cursor)
void HexView::SetCursor(uint64 _cursor)
{
cursor = _cursor;
if(cursor > total)
cursor = total - 1;
if(cursor < 0)
@ -294,7 +313,7 @@ void HexView::LeftDown(Point p, dword)
x = p.x - x;
int q = x / fcx3;
if(x - q * fcx3 < 2 * fsz.cx && q < columns) {
int64 c = sc + rowi * columns + q;
uint64 c = sc + rowi * columns + q;
if(c < total)
SetCursor(c);
}
@ -303,7 +322,7 @@ void HexView::LeftDown(Point p, dword)
if(p.x >= tx) {
int q = (p.x - tx) / fsz.cx;
if(q >= 0 && q < columns) {
int64 c = sc + rowi * columns + q;
uint64 c = sc + rowi * columns + q;
if(c < total)
SetCursor(c);
}
@ -383,7 +402,7 @@ void HexView::StdGoto(const String& s)
if(p.Char2('0', 'x') || p.Char('$') || p.Char('#'))
n = 16;
if(p.IsNumber(n)) {
int64 a = p.ReadNumber(n);
uint64 a = p.ReadNumber(n);
if(a >= 0 && a < total) {
SetCursor(a);
SetSc(a);
@ -435,7 +454,7 @@ void HexView::CharsetMenu(Bar& bar)
void HexView::StdMenu(Bar& bar)
{
bar.Add("Go to..", THISBACK(Goto))
bar.Add("Go to..", [=] { WhenGotoDlg(); })
.Key(K_CTRL_G);
bar.Add("Columns", THISBACK(ColumnsMenu));
bar.Add("Charset", THISBACK(CharsetMenu));
@ -489,6 +508,7 @@ HexView::HexView()
WhenBar = THISBACK(StdMenu);
CtrlLayoutOKCancel(go, "Go to");
WhenGoto = THISBACK(StdGoto);
WhenGotoDlg = THISBACK(Goto);
}
}

View file

@ -17,11 +17,13 @@ private:
int data[80];
int mode;
bool longmode;
bool empty = false;
void PrintValue(Draw& w, int x, int y, int bytes, bool be);
public:
void SetPos(int64 p, bool lm) { pos = p; longmode = lm; }
void SetEmpty() { empty = true; Refresh(); }
void SetPos(int64 p, bool lm) { pos = p; longmode = lm; empty = false; Refresh(); }
void Set(int i, int d) { ASSERT(i >= 0 && i < 80); data[i] = d; Refresh(); }
void SetMode(int m);
int GetMode() const { return mode; }
@ -45,7 +47,10 @@ private:
int fixed;
int columns, rows, bytes;
int sbm;
int64 sc, cursor, total;
uint64 sc = 0;
uint64 cursor = 0;
uint64 total = 0;
uint64 start = 0;
byte charset;
ScrollBar sb;
@ -66,24 +71,26 @@ public:
Event<Bar&> WhenBar;
Event<const String&> WhenGoto;
Event<> WhenGotoDlg;
void ColumnsMenu(Bar& bar);
void CharsetMenu(Bar& bar);
void InfoMenu(Bar& bar);
void StdMenu(Bar& bar);
void ColumnsMenu(Bar& bar);
void CharsetMenu(Bar& bar);
void InfoMenu(Bar& bar);
void StdMenu(Bar& bar);
void StdGoto(const String& text);
void StdGoto(const String& text);
void GotoAddHistory() { go.text.AddHistory(); }
void GotoAddHistory() { go.text.AddHistory(); }
bool IsLongMode() const { return total > 0xffffffff; }
void SetTotal(int64 _total);
void SetSc(int64 address);
int64 GetSc() const { return sc; }
void SetCursor(int64 address);
int64 GetCursor() const { return cursor; }
bool IsLongMode() const { return total > 0xffffffff; }
void SetStart(uint64 start);
void SetTotal(uint64 _total);
void SetSc(uint64 address);
uint64 GetSc() const { return sc; }
void SetCursor(uint64 address);
uint64 GetCursor() const { return cursor; }
void SerializeSettings(Stream& s);
void SerializeSettings(Stream& s);
HexView& SetFont(Font fnt);
HexView& Charset(byte chrset) { charset = chrset; Refresh(); return *this; }

View file

@ -20,6 +20,7 @@ file
GdbCmd.cpp,
GdbData.cpp,
Gdb.cpp,
GdbMem.cpp,
GdbUtils.h,
GdbUtils.cpp,
PDB readonly separator,

View file

@ -617,27 +617,40 @@ void Gdb::Periodic()
Gdb::Gdb()
: gdb_utils(GdbUtilsFactory().Create())
{
auto Mem = [=](Bar& bar, ArrayCtrl& h) {
String s = h.GetKey();
if(s.GetCount()) {
if(!IsAlpha(*s))
s = '(' + s + ')';
bar.Add("Memory at &&" + s, [=] { tab.Set(memory); MemoryLoad('&' + s, 2048, true); });
bar.Add("Memory at " + s, [=] { tab.Set(memory); MemoryLoad(s, 2048, true); });
}
};
locals.NoHeader();
locals.AddColumn("", 1);
locals.AddColumn("", 6);
locals.EvenRowColor();
locals.WhenSel = THISBACK1(SetTree, &locals);
locals.WhenBar = [=](Bar& bar) { Mem(bar, locals); };
watches.NoHeader();
watches.AddColumn("", 1).Edit(watchedit);
watches.AddColumn("", 6);
watches.Inserting().Removing();
watches.EvenRowColor();
watches.WhenSel = THISBACK1(SetTree, &watches);
watches.WhenBar = [=](Bar& bar) { Mem(bar, watches); };
autos.NoHeader();
autos.AddColumn("", 1);
autos.AddColumn("", 6);
autos.EvenRowColor();
autos.WhenSel = THISBACK1(SetTree, &autos);
autos.WhenBar = [=](Bar& bar) { Mem(bar, autos); };
self.NoHeader();
self.AddColumn("", 1);
self.AddColumn("", 6);
self.EvenRowColor();
self.WhenSel = THISBACK1(SetTree, &self);
self.WhenBar = [=](Bar& bar) { Mem(bar, self); };
cpu.Columns(3);
cpu.ItemHeight(Courier(Ctrl::HorzLayoutZoom(12)).GetCy());
@ -647,11 +660,13 @@ Gdb::Gdb()
tab.Add(watches.SizePos(), "Watches");
tab.Add(self.SizePos(), "this");
tab.Add(cpu.SizePos(), "CPU");
pane.Add(threads.LeftPosZ(250, 150).TopPos(2));
tab.Add(memory.SizePos(), "Memory");
pane.Add(threads.LeftPosZ(330, 150).TopPos(2));
memory.WhenGotoDlg = [=] { MemoryGoto(); };
int bcx = min(EditField::GetStdHeight(), DPI(16));
pane.Add(frame.HSizePos(Zx(404), 2 * bcx).TopPos(2));
pane.Add(frame.HSizePos(Zx(484), 2 * bcx).TopPos(2));
pane.Add(frame_up.RightPos(bcx, bcx).TopPos(2, EditField::GetStdHeight()));
frame_up.SetImage(DbgImg::FrameUp());
frame_up << [=] { FrameUpDown(-1); };

View file

@ -76,7 +76,10 @@ public:
void SetTree(ArrayCtrl *a);
void OnTreeBar(Bar& bar);
void OnTreeExpand(int node);
void MemoryGoto();
void MemoryLoad(const String& adr, int count, bool showerror);
void Memory();
void OnValueCopyToClipboard(const Value& val);
Value ObtainValueFromTreeCursor(int cursor) const;
@ -86,12 +89,12 @@ public:
void CopyDisas();
void BreakRunning();
bool Create(One<Host>&& host, const String& exefile, const String& cmdline, bool console);
TimeCallback periodic; // Period check for killed console
void Periodic();
virtual ~Gdb() override;
Gdb();
@ -118,7 +121,14 @@ protected:
StaticRect pane;
Splitter split;
TreeCtrl tree;
struct GdbHexView : HexView {
uint64 start;
Vector<byte> data;
virtual int Byte(int64 i) { return i >= 0 && i < data.GetCount() ? data[(int)i] : 0; }
}
memory;
VectorMap<String, String> expression_cache;
WithQuickwatchLayout<TopWindow> quickwatch;

View file

@ -5,3 +5,12 @@ LAYOUT(QuickwatchLayout, 400, 372)
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(76, 64).BottomPosZ(6, 22))
END_LAYOUT
LAYOUT(GotoMemoryLayout, 384, 64)
ITEM(Label, dv___0, SetLabel(t_("Address")).LeftPosZ(8, 48).TopPosZ(8, 19))
ITEM(EditString, adr, LeftPosZ(60, 208).TopPosZ(8, 19))
ITEM(Label, dv___2, SetLabel(t_("bytes")).LeftPosZ(276, 36).TopPosZ(8, 19))
ITEM(WithDropChoice<EditInt>, count, LeftPosZ(312, 64).TopPosZ(8, 19))
ITEM(Button, ok, SetLabel(t_("OK")).HCenterPosZ(64, 84).BottomPosZ(6, 22))
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(8, 64).BottomPosZ(6, 22))
END_LAYOUT

View file

@ -280,6 +280,7 @@ void Gdb::ObtainData()
case 2: Watches(); break;
case 3: Self(); break;
case 4: Cpu(); break;
case 5: Memory(); break;
}
}

View file

@ -0,0 +1,53 @@
#include "Debuggers.h"
void Gdb::MemoryGoto()
{
WithGotoMemoryLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, "Memory view");
dlg.count <<= memory.data.GetCount();
dlg.count.AddList(1024);
dlg.count.AddList(2048);
dlg.count.AddList(4096);
dlg.count <<= 2048;
dlg.adr <<= FormatHex((void *)memory.start);
if(dlg.Execute() != IDOK)
return;
MemoryLoad(~dlg.adr, ~dlg.count, true);
}
void Gdb::MemoryLoad(const String& adr, int count, bool showerror)
{
memory.start = 0;
memory.data.Clear();
String error;
for(String s : Split(FastCmd("x /" + AsString(clamp(count, 1, 1024*1024)) + "xb " + adr), '\n')) {
if(IsNull(error))
error = TrimBoth(s);
CParser p(s);
while(!p.IsEof())
if(p.Char2('0', 'x') && p.IsNumber(16)) {
uint64 a = p.ReadNumber(16);
if(!memory.start)
memory.start = a;
while(!p.IsEof())
if(p.Char2('0', 'x') && p.IsNumber(16))
memory.data.Add((byte)p.ReadNumber(16));
else
p.SkipTerm();
}
else
p.SkipTerm();
}
if(showerror && !memory.start && error.GetCount())
Exclamation("\1" + error);
memory.SetStart(memory.start);
memory.SetTotal(memory.data.GetCount());
memory.SetSc(0);
memory.SetCursor(0);
}
void Gdb::Memory()
{
if(memory.data.GetCount())
MemoryLoad("0x" + FormatIntHex((void *)memory.start), memory.data.GetCount(), false);
}