mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
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:
parent
090e1839ca
commit
b92b70807d
8 changed files with 153 additions and 37 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ file
|
|||
GdbCmd.cpp,
|
||||
GdbData.cpp,
|
||||
Gdb.cpp,
|
||||
GdbMem.cpp,
|
||||
GdbUtils.h,
|
||||
GdbUtils.cpp,
|
||||
PDB readonly separator,
|
||||
|
|
|
|||
|
|
@ -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); };
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ void Gdb::ObtainData()
|
|||
case 2: Watches(); break;
|
||||
case 3: Self(); break;
|
||||
case 4: Cpu(); break;
|
||||
case 5: Memory(); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
53
uppsrc/ide/Debuggers/GdbMem.cpp
Normal file
53
uppsrc/ide/Debuggers/GdbMem.cpp
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue