ide: POSIX debugging of console applications now launches console #507

git-svn-id: svn://ultimatepp.org/upp/trunk@6677 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2013-12-19 12:36:35 +00:00
parent 094ef62883
commit 7bc553fee0
10 changed files with 168 additions and 24 deletions

View file

@ -134,25 +134,27 @@ bool LocalProcess::DoStart(const char *command, bool spliterr, const char *envpt
p++;
else {
args.Add(cmd_out);
while(*p && (byte)*p > ' ')
if(*p == '\\') {
while(*p && (byte)*p > ' ') {
int c = *p;
if(c == '\\') {
if(*++p)
*cmd_out++ = *p++;
}
else if(*p == '\"') {
else if(c == '\"' || c == '\'') {
p++;
while(*p && *p != '\"')
while(*p && *p != c)
if(*p == '\\') {
if(*++p)
*cmd_out++ = *p++;
}
else
*cmd_out++ = *p++;
if(*p == '\"')
if(*p == c)
p++;
}
else
*cmd_out++ = *p++;
}
*cmd_out++ = '\0';
}

View file

@ -62,6 +62,10 @@ public:
bool Start(const char *cmdline, const char *envptr = NULL) { return DoStart(cmdline, false, envptr); }
bool Start2(const char *cmdline, const char *envptr = NULL) { return DoStart(cmdline, true, envptr); }
#ifdef PLATFORM_POSIX
int GetPid() const { return pid; }
#endif
LocalProcess& ConvertCharset(bool b = true) { convertcharset = b; return *this; }
LocalProcess& NoConvertCharset() { return ConvertCharset(false); }

View file

@ -154,8 +154,8 @@ void Ide::BuildAndExtDebugFile()
BuildAndDebug0(editfile);
}
One<Debugger> GdbCreate(One<Host> host, const String& exefile, const String& cmdline);
One<Debugger> Gdb_MI2Create(One<Host> host, const String& exefile, const String& cmdline);
One<Debugger> GdbCreate(One<Host> host, const String& exefile, const String& cmdline, bool console);
One<Debugger> Gdb_MI2Create(One<Host> host, const String& exefile, const String& cmdline, bool console);
#ifdef PLATFORM_WIN32
One<Debugger> CdbCreate(One<Host> host, const String& exefile, const String& cmdline);
One<Debugger> PdbCreate(One<Host> host, const String& exefile, const String& cmdline);
@ -175,19 +175,22 @@ void Ide::BuildAndDebug(bool runto)
host->ChDir(Nvl(rundir, GetFileFolder(target)));
HideBottom();
editor.Disable();
bool console = FindIndex(SplitFlags(mainconfigparam, true), "GUI") < 0 || forceconsole;
#ifdef COMPILER_MSC
if(builder == "GCC")
if(gdbSelector)
debugger = Gdb_MI2Create(host, target, runarg);
debugger = Gdb_MI2Create(host, target, runarg, console);
else
debugger = GdbCreate(host, target, runarg);
debugger = GdbCreate(host, target, runarg, console);
else
debugger = PdbCreate(host, target, runarg);
#else
if(gdbSelector)
debugger = Gdb_MI2Create(host, target, runarg);
debugger = Gdb_MI2Create(host, target, runarg, console);
else
debugger = GdbCreate(host, target, runarg);
debugger = GdbCreate(host, target, runarg, console);
#endif
if(!debugger) return;
debuglock = 0;

View file

@ -117,6 +117,8 @@ String Dbg::Cmd(const char *command)
GuiSleep(sleep);
Ctrl::ProcessEvents();
sleep = min(20, sleep + max(1, 3 * sleep / 2));
if(TTYQuit())
Stop();
}
Unlock();
#ifdef _DEBUG
@ -141,6 +143,8 @@ String Dbg::FastCmd(const char *command)
String s;
// if(!lock)
Sleep(0);
if(TTYQuit())
Stop();
if(!dbg->Read(s)) {
LLOG(result);
PutVerbose(result);
@ -231,5 +235,4 @@ Dbg::Dbg()
quickwatch.Icon(DbgImg::QuickWatch());
Transparent();
// log.Open(ConfigFile("debug.log"));
}

View file

@ -14,6 +14,14 @@
typedef uintptr_t adr_t;
#ifdef PLATFORM_POSIX
String CreateDebugTTY();
void KillDebugTTY();
bool TTYQuit();
#endif
String GdbCommand(bool console);
class DbgDisas : public Ctrl {
public:
virtual void Paint(Draw& w);
@ -162,11 +170,16 @@ struct Gdb : Dbg {
void CopyStack();
void CopyDisas();
bool Create(One<Host> host, const String& exefile, const String& cmdline);
bool Create(One<Host> host, const String& exefile, const String& cmdline, bool console);
// Period check for killed console
TimeCallback periodic;
void Periodic();
typedef Gdb CLASSNAME;
virtual ~Gdb();
Gdb();
};
#include "Gdb_MI2.h"

View file

@ -6,11 +6,12 @@ uses
HexView;
file
MIValue.h,
MIValue.cpp,
Debuggers.h,
Debuggers.iml,
Gdb.lay,
MIValue.h,
MIValue.cpp,
Terminal.cpp,
Disas.cpp,
Dbg.cpp,
Gdb.cpp,

View file

@ -551,10 +551,10 @@ bool Gdb::Key(dword key, int count)
return Ctrl::Key(key, count);
}
bool Gdb::Create(One<Host> _host, const String& exefile, const String& cmdline)
bool Gdb::Create(One<Host> _host, const String& exefile, const String& cmdline, bool console)
{
host = _host;
dbg = host->StartProcess("gdb " + GetHostPath(exefile));
dbg = host->StartProcess(GdbCommand(console) + GetHostPath(exefile));
if(!dbg) {
Exclamation("Error invoking gdb !");
return false;
@ -593,12 +593,24 @@ Gdb::~Gdb()
{
IdeRemoveBottom(*this);
IdeRemoveRight(disas);
KillDebugTTY();
}
One<Debugger> GdbCreate(One<Host> host, const String& exefile, const String& cmdline)
void Gdb::Periodic()
{
if(TTYQuit())
Stop();
}
Gdb::Gdb()
{
periodic.Set(-50, THISBACK(Periodic));
}
One<Debugger> GdbCreate(One<Host> host, const String& exefile, const String& cmdline, bool console)
{
Gdb *dbg = new Gdb;
if(!dbg->Create(host, exefile, cmdline)) {
if(!dbg->Create(host, exefile, cmdline, console)) {
delete dbg;
return NULL;
}

View file

@ -218,6 +218,12 @@ bool Gdb_MI2::Tip(const String& exp, CodeEditor::MouseTip& mt)
// CONSTRUCTOR / DESTRUCTOR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gdb_MI2::Periodic()
{
if(TTYQuit())
Stop();
}
Gdb_MI2::Gdb_MI2()
{
CtrlLayout(regs);
@ -319,12 +325,15 @@ Gdb_MI2::Gdb_MI2()
started = false;
stopped = false;
periodic.Set(-50, THISBACK(Periodic));
}
Gdb_MI2::~Gdb_MI2()
{
IdeRemoveBottom(*this);
IdeRemoveRight(disas);
KillDebugTTY();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1716,10 +1725,10 @@ void Gdb_MI2::ExplorerMenu(Bar& bar)
//////////////////////////////////////////////////////////////////////////////////////////////////////
// create GDB process and initializes it
bool Gdb_MI2::Create(One<Host> _host, const String& exefile, const String& cmdline)
bool Gdb_MI2::Create(One<Host> _host, const String& exefile, const String& cmdline, bool console)
{
host = _host;
dbg = host->StartProcess("gdb " + GetHostPath(exefile) + " --interpreter=mi -q");
dbg = host->StartProcess(GdbCommand(console) + GetHostPath(exefile) + " --interpreter=mi -q");
if(!dbg) {
Exclamation(t_("Error invoking gdb !"));
return false;
@ -1776,10 +1785,10 @@ bool Gdb_MI2::Create(One<Host> _host, const String& exefile, const String& cmdli
return true;
}
One<Debugger> Gdb_MI2Create(One<Host> host, const String& exefile, const String& cmdline)
One<Debugger> Gdb_MI2Create(One<Host> host, const String& exefile, const String& cmdline, bool console)
{
Gdb_MI2 *dbg = new Gdb_MI2;
if(!dbg->Create(host, exefile, cmdline))
if(!dbg->Create(host, exefile, cmdline, console))
{
delete dbg;
return NULL;

View file

@ -212,6 +212,10 @@ class Gdb_MI2 : public Debugger, public ParentCtrl
// lock/unlock debugger controls
void Lock();
void Unlock();
// Period check for killed console
TimeCallback periodic;
void Periodic();
String GetHostPath(const String& path) { return host->GetHostPath(path); }
String GetLocalPath(const String& path) { return host->GetLocalPath(path); }
@ -233,7 +237,7 @@ class Gdb_MI2 : public Debugger, public ParentCtrl
virtual bool Tip(const String& exp, CodeEditor::MouseTip& mt);
// create GDB process and initializes it
bool Create(One<Host> _host, const String& exefile, const String& cmdline);
bool Create(One<Host> _host, const String& exefile, const String& cmdline, bool console);
Gdb_MI2();
virtual ~Gdb_MI2();

View file

@ -0,0 +1,93 @@
#include "Debuggers.h"
#ifdef PLATFORM_POSIX
void Do_ps(VectorMap<String, String>& pids, Index<String>& ttys, const String& cmd)
{
pids.Clear();
ttys.Clear();
Vector<String> ps = Split(Sys(cmd), '\n');
for(int i = 1; i < ps.GetCount(); i++) {
Vector<String> ss = Split(ps[i], ' ');
if(ss.GetCount() >= 2) {
if(IsDigit(*ss[0]) && IsAlNum(*ss[1])) {
pids.Add(ss[1], ss[0]);
ttys.FindAdd(ss[1]);
}
}
}
}
static VectorMap<String, String> sPid;
static String sTTY;
String CreateDebugTTY()
{ // The method is far from ideal and reliable, but should work most of time
sTTY.Clear();
Index<String> tty0, tty;
Do_ps(sPid, tty0, "ps -A");
IGNORE_RESULT(chdir(GetHomeDirectory()));
static const char *term[] = {
"/usr/bin/mate-terminal -e 'tail -f /dev/null'",
"/usr/bin/gnome-terminal -e 'tail -f /dev/null'",
"/usr/bin/konsole -e 'tail -f /dev/null'",
"/usr/bin/xterm -e 'tail -f /dev/null'",
};
for(int i = 0; i < __countof(term); i++) {
if(FileExists(Split(term[i], ' ')[0])) {
LocalProcess(term[i]).Detach();
for(int i = 0; i < 10; i++) { // Wait for the new TTY to appear
Do_ps(sPid, tty, "ps -A");
for(int i = 0; i < tty.GetCount(); i++)
if(tty0.Find(tty[i]) < 0) {
sTTY = tty[i];
return "/dev/" + sTTY;
}
Sleep(200);
}
}
}
return Null;
}
void KillDebugTTY()
{
Index<String> tty;
Do_ps(sPid, tty, "ps -A");
if(sTTY.GetCount())
for(int q = sPid.Find(sTTY); q >= 0; q = sPid.FindNext(q)) {
Sys("kill -9 " + sPid[q]);
}
sTTY.Clear();
}
bool TTYQuit()
{
if(sTTY.GetCount()) {
int fd = open("/dev/" + sTTY, O_RDWR | O_NONBLOCK);
if(fd < 0)
return true;
close(fd);
return false;
}
return false;
}
String GdbCommand(bool console)
{
String gdb = "gdb ";
#ifdef PLATFORM_POSIX
if(console) {
String tty = CreateDebugTTY();
if(tty.GetCount())
gdb << "-tty=" << tty << ' ';
}
#endif
return gdb;
}
#endif