mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
235 lines
4.8 KiB
C++
235 lines
4.8 KiB
C++
#include "Debuggers.h"
|
|
|
|
#define LLOG(x) // LOG(x)
|
|
|
|
#define IMAGECLASS DbgImg
|
|
#define IMAGEFILE <ide/Debuggers/Debuggers.iml>
|
|
#include <Draw/iml_source.h>
|
|
|
|
const char *FindTag(const char *txt, const char *tag)
|
|
{
|
|
while(*txt) {
|
|
const char *q = txt;
|
|
const char *t = tag;
|
|
while(*q == *t) {
|
|
q++;
|
|
t++;
|
|
if(*t == '\0') return txt;
|
|
}
|
|
txt++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
const char *AfterTag(const char *txt, const char *tag)
|
|
{
|
|
while(*txt) {
|
|
const char *q = txt;
|
|
const char *t = tag;
|
|
while(*q == *t) {
|
|
q++;
|
|
t++;
|
|
if(*t == '\0') return q;
|
|
}
|
|
txt++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
const char *AfterHeading(const char *txt, const char *heading)
|
|
{
|
|
while(*heading)
|
|
if(*txt++ != *heading++)
|
|
return false;
|
|
return txt;
|
|
}
|
|
|
|
void RedDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword s) const {
|
|
w.DrawRect(r, paper);
|
|
DrawSmartText(w, r.left, r.top, r.Width(), String(q), StdFont(), LtRed());
|
|
}
|
|
|
|
VectorMap<String, String> DataMap(const ArrayCtrl& data)
|
|
{
|
|
VectorMap<String, String> m;
|
|
for(int i = 0; i < data.GetCount(); i++)
|
|
m.Add(data.Get(i, 0), data.Get(i, 1));
|
|
return m;
|
|
}
|
|
|
|
void MarkChanged(const VectorMap<String, String>& m, ArrayCtrl& data)
|
|
{
|
|
for(int i = 0; i < data.GetCount(); i++) {
|
|
int q = m.Find(data.Get(i, 0));
|
|
if(q >= 0 && m[q] != data.Get(i, 1))
|
|
data.SetDisplay(i, 1, Single<RedDisplay>());
|
|
else
|
|
data.SetDisplay(i, 1, StdDisplay());
|
|
}
|
|
}
|
|
|
|
void Dbg::Lock()
|
|
{
|
|
IdeDebugLock();
|
|
watches.Disable();
|
|
locals.Disable();
|
|
frame.Disable();
|
|
dlock.Show();
|
|
}
|
|
|
|
void Dbg::Unlock()
|
|
{
|
|
if(IdeDebugUnLock()) {
|
|
watches.Enable();
|
|
locals.Enable();
|
|
frame.Enable();
|
|
dlock.Hide();
|
|
}
|
|
}
|
|
|
|
String Dbg::Cmd(const char *command)
|
|
{
|
|
if(!dbg || !dbg->IsRunning() || IdeIsDebugLock()) return Null;
|
|
#ifdef _DEBUG
|
|
TimeStop ts;
|
|
#endif
|
|
Lock();
|
|
if(command) {
|
|
LLOG("Cmd: " << command);
|
|
dbg->Write(String(command) + "\n"); // TRC 04/10/11: must not use \r\n, LINUX doesn't like it
|
|
PutVerbose(command);
|
|
}
|
|
String result;
|
|
int sleep = 0;
|
|
while(dbg) {
|
|
String s;
|
|
if(!dbg->Read(s)) {
|
|
LLOG(result);
|
|
PutVerbose(result);
|
|
PutVerbose("Debugger terminated");
|
|
break;
|
|
}
|
|
if(!s.IsEmpty() && Result(result, s)) {
|
|
LLOG(result);
|
|
PutVerbose(result);
|
|
break;
|
|
}
|
|
GuiSleep(sleep);
|
|
Ctrl::ProcessEvents();
|
|
sleep = min(20, sleep + max(1, 3 * sleep / 2));
|
|
}
|
|
Unlock();
|
|
#ifdef _DEBUG
|
|
if(command)
|
|
LLOG("Time of `" << command <<"` " << ts);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
String Dbg::FastCmd(const char *command)
|
|
{
|
|
if(!dbg || !dbg->IsRunning() || IdeIsDebugLock()) return Null;
|
|
bool lock = false;
|
|
if(command) {
|
|
LLOG("FastCmd: " << command);
|
|
dbg->Write(String(command) + "\n"); // TRC 04/10/20: must not use \r\n as LINUX hates it
|
|
PutVerbose(command);
|
|
}
|
|
String result;
|
|
TimeStop ts;
|
|
while(dbg) {
|
|
String s;
|
|
// if(!lock)
|
|
Sleep(0);
|
|
if(!dbg->Read(s)) {
|
|
LLOG(result);
|
|
PutVerbose(result);
|
|
PutVerbose("dbg terminated");
|
|
break;
|
|
}
|
|
if(!s.IsEmpty() && Result(result, s)) {
|
|
LLOG(result);
|
|
LLOG("Result length: " << result.GetLength());
|
|
if(result.GetLength() < 1000)
|
|
PutVerbose(result);
|
|
break;
|
|
}
|
|
if(ts.Elapsed() > 4000) {
|
|
if(!lock) {
|
|
lock = true;
|
|
Lock();
|
|
}
|
|
// Ctrl::GuiSleep()(20);
|
|
Ctrl::ProcessEvents();
|
|
}
|
|
}
|
|
if(lock)
|
|
Unlock();
|
|
#ifdef _DEBUG
|
|
if(command)
|
|
LLOG("Time of `" << command <<"` " << ts);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
void Dbg::Stop()
|
|
{
|
|
if(dbg && dbg->IsRunning())
|
|
dbg->Kill();
|
|
}
|
|
|
|
bool Dbg::IsFinished()
|
|
{
|
|
return !dbg->IsRunning() && !IdeIsDebugLock();
|
|
}
|
|
|
|
Dbg::Dbg()
|
|
{
|
|
CtrlLayout(regs);
|
|
regs.Height(regs.GetLayoutSize().cy);
|
|
AddReg("eax", ®s.eax);
|
|
AddReg("ebx", ®s.ebx);
|
|
AddReg("ecx", ®s.ecx);
|
|
AddReg("edx", ®s.edx);
|
|
AddReg("esi", ®s.esi);
|
|
AddReg("edi", ®s.edi);
|
|
AddReg("ebp", ®s.ebp);
|
|
AddReg("esp", ®s.esp);
|
|
regs.Color(SColorLtFace);
|
|
regs.AddFrame(TopSeparatorFrame());
|
|
regs.AddFrame(RightSeparatorFrame());
|
|
|
|
locals.NoHeader();
|
|
locals.AddColumn("", 1);
|
|
locals.AddColumn("", 6);
|
|
watches.NoHeader();
|
|
watches.AddColumn("", 1).Edit(watchedit);
|
|
watches.AddColumn("", 6);
|
|
watches.Inserting().Removing();
|
|
autos.NoHeader();
|
|
autos.AddColumn("", 1);
|
|
autos.AddColumn("", 6);
|
|
Add(tab.SizePos());
|
|
tab.Add(watches.SizePos(), "Watches");
|
|
tab.Add(locals.SizePos(), "Locals");
|
|
tab.Add(autos.SizePos(), "Autos");
|
|
Add(frame.HSizePos(200, 0).TopPos(2, EditField::GetStdHeight()));
|
|
frame.Ctrl::Add(dlock.SizePos());
|
|
dlock = " Running..";
|
|
dlock.SetFrame(BlackFrame());
|
|
dlock.SetInk(Red);
|
|
dlock.NoTransparent();
|
|
dlock.Hide();
|
|
|
|
CtrlLayoutOKCancel(quickwatch, "Quick watch");
|
|
quickwatch.WhenClose = quickwatch.Breaker(IDCANCEL);
|
|
quickwatch.value.SetReadOnly();
|
|
quickwatch.value.SetFont(Courier(12));
|
|
quickwatch.Sizeable().Zoomable();
|
|
quickwatch.NoCenter();
|
|
quickwatch.SetRect(0, 150, 300, 400);
|
|
quickwatch.Icon(DbgImg::QuickWatch());
|
|
|
|
Transparent();
|
|
// log.Open(ConfigFile("debug.log"));
|
|
}
|