3) allows user to stop debuggee in I/O or loop. User has to hit the stop button twice. Once to stop gdb, then again to kill the debuggee.
I haven't yet figured out a fix for crashes when deleting a breakpoint.
Index: debuggerdriver.cpp
===================================================================
--- debuggerdriver.cpp (revision 3654)
+++ debuggerdriver.cpp (working copy)
@@ -5,6 +5,7 @@
DebuggerDriver::DebuggerDriver(DebuggerGDB* plugin)
: m_pDBG(plugin),
m_ProgramIsStopped(true),
+ m_IsStarted(false), //(pecan 2007/3/01)
m_ChildPID(0),
m_pBacktrace(0),
m_pDisassembly(0),
Index: debuggergdb.cpp
===================================================================
--- debuggergdb.cpp (revision 3654)
+++ debuggergdb.cpp (working copy)
@@ -227,12 +227,18 @@
m_pBreakpointsWindow(0),
m_pExamineMemoryDlg(0),
m_pThreadsDlg(0),
- m_pProject(0)
+ m_pProject(0),
+ m_GDBInputKnt(0)
{
if(!Manager::LoadResource(_T("debugger.zip")))
{
NotifyMissingFile(_T("debugger.zip"));
}
+ // vars for Linux console //(pecan 2007/2/06)
+ m_bIsConsole = false;
+ m_nConsolePid = 0;
+ m_ConsoleTty = wxEmptyString;
+
}
DebuggerGDB::~DebuggerGDB()
@@ -789,7 +795,11 @@
{
return !m_State.HasDriver() || m_State.GetDriver()->IsStopped();
}
-
+bool DebuggerGDB::IsStarted() //(pecan 2007/3/01)
+{
+ if (!m_State.HasDriver()) return false;
+ return m_State.GetDriver()->IsStarted();
+}
int DebuggerGDB::Debug()
{
// if already running, return
@@ -1021,6 +1031,21 @@
m_State.GetDriver()->Prepare(target && target->GetTargetType() == ttConsoleOnly);
m_State.ApplyBreakpoints();
+ #ifdef __WXGTK__ //(pecan 2007/2/05)
+ // create xterm and issue tty "/dev/pts/#" to GDB where
+ // # is the tty for the newly created xterm
+ m_bIsConsole = (target && target->GetTargetType() == ttConsoleOnly);
+ if (m_bIsConsole)
+ {
+ if (RunNixConsole() > 0 )
+ { wxString gdbTtyCmd;
+ gdbTtyCmd << wxT("tty ") << m_ConsoleTty;
+ m_State.GetDriver()->QueueCommand(new DebuggerCmd(m_State.GetDriver(), gdbTtyCmd, true));
+ DebugLog(wxString::Format( _("Queued:[%s]"), gdbTtyCmd.c_str()) );
+ }
+ }//if
+ #endif//def __WXGTK__
+
// Don't issue 'run' if attaching to a process (Bug #1391904)
if (m_PidToAttach == 0)
m_State.GetDriver()->Start(m_BreakOnEntry);
@@ -1503,12 +1528,24 @@
void DebuggerGDB::Stop()
{
+ // m_Process is PipedProcess I/O; m_Pid is debugger pid
if (m_pProcess && m_Pid)
{
- if (IsStopped())
+ //-if (IsStopped()) //no Driver || m_IsStopped
+ //-if (IsStopped() && IsStarted() ) //(pecan 2007/3/01)
+ DebugLog(wxString::Format(wxT("IsStopped:[%d] IsStarted:[%d]"),IsStopped(),IsStarted()));
+ if (IsStarted() ) //(pecan 2007/3/01)
{
RunCommand(CMD_STOP);
m_pProcess->CloseOutput();
+ #ifdef __WXGTK__
+ // kill any linux console //(pecan 2007/2/06)
+ if ( m_bIsConsole && (m_nConsolePid > 0) )
+ {
+ ::wxKill(m_nConsolePid);
+ m_nConsolePid = 0;
+ }
+ #endif
}
else
{
@@ -1521,7 +1558,8 @@
_("Debug"), wxOK | wxICON_EXCLAMATION);
else
#endif
- wxKill(pid, wxSIGINT);
+ if (pid > 0)
+ wxKill(pid, wxSIGINT);
#else
m_pProcess->CloseOutput();
wxKillError err = m_pProcess->Kill(m_Pid, wxSIGKILL);
@@ -1909,12 +1947,19 @@
void DebuggerGDB::OnGDBOutput(wxCommandEvent& event)
{
+ ++m_GDBInputKnt;
wxString msg = event.GetString();
if (!msg.IsEmpty())
{
// Manager::Get()->GetMessageManager()->Log(m_PageIndex, _T("O>>> %s"), msg.c_str());
ParseOutput(msg);
}
+ --m_GDBInputKnt;
+ if ( (not m_pProcess) && m_State.HasDriver() && (m_GDBInputKnt==0) )
+ { m_State.StopDriver();
+ DebugLog(wxT("OnGDBOutput() closed m_State.Driver"));
+ }
+
}
void DebuggerGDB::OnGDBError(wxCommandEvent& event)
@@ -1937,7 +1982,14 @@
// m_pProcess = 0L;
ClearActiveMarkFromAllEditors();
- m_State.StopDriver();
+ // closing the GDB driver here causes crashes because input msgs
+ // are still queued up in OnGDBOutput/ParseOutput //(pecan 2007/2/09)
+ //-m_State.StopDriver();
+ if ( (not m_pProcess) && m_State.HasDriver() && (m_GDBInputKnt==0) )
+ { m_State.StopDriver();
+ DebugLog(wxT("OnGDBTerminate() closed m_State.Driver"));
+ }
+
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Debugger finished with status %d"), m_LastExitCode);
if (m_NoDebugInfo)
@@ -2198,3 +2250,95 @@
{
Configure();
}
+// ----------------------------------------------------------------------------
+int DebuggerGDB::RunNixConsole()
+// ----------------------------------------------------------------------------
+{
+ // start the xterm and put the shell to sleep with -e sleep 80000
+ // fetch the xterm tty so we can issue to gdb a "tty /dev/pts/#"
+ // redirecting program stdin/stdout/stderr to the xterm console.
+
+ #ifndef __WXMSW__
+ wxString cmd;
+ wxString title = wxT("Program Console");
+ m_nConsolePid = 0;
+ // for non-win platforms, use m_ConsoleTerm to run the console app
+ wxString term = Manager::Get()->GetConfigManager(_T("app"))->Read(_T("/console_terminal"), DEFAULT_CONSOLE_TERM);
+ //term.Replace(_T("$TITLE"), _T("'") + _T("*nixConsole") + _T("'"));
+ term.Replace(_T("$TITLE"), _T("'") + title + _T("'"));
+ cmd << term << _T(" ");
+ cmd << wxT("sleep ");
+ cmd << 80000 + ::wxGetProcessId(); //make a unique sleep command
+
+ Manager::Get()->GetMacrosManager()->ReplaceEnvVars(cmd);
+ //Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Executing: %s"), cmd.c_str() );
+ DebugLog(wxString::Format( _("Executing: %s"), cmd.c_str()) );
+ //start xterm -e sleep {some unique # of seconds}
+ m_nConsolePid = wxExecute(cmd, wxEXEC_ASYNC);
+ if (m_nConsolePid <= 0) return -1;
+
+ // Issue the PS command with to get the /dev/tty device name
+ // First, wait for the xterm to settle down, else PS won't see the sleep task
+ Manager::Yield();
+ ::wxSleep(1);
+ m_ConsoleTty = GetConsoleTty(m_nConsolePid);
+ if (not m_ConsoleTty.IsEmpty() )
+ return m_nConsolePid;
+ // failed to find the console tty
+ DebugLog( wxT("Console Execution error:failed to find console tty."));
+ ::wxKill(m_nConsolePid);
+ m_nConsolePid = 0;
+ #endif//ndef __WWXMSW__
+ return -1;
+}
+// ----------------------------------------------------------------------------
+wxString DebuggerGDB::GetConsoleTty(int ConsolePid)
+// ----------------------------------------------------------------------------
+{
+ // execute the ps -x command and read PS output to get the /dev/tty field
+
+ unsigned long ConsPid = ConsolePid;
+ wxString psCmd;
+ wxArrayString psOutput;
+ wxArrayString psErrors;
+
+ psCmd << wxT("ps x");
+ DebugLog(wxString::Format( _("Executing: %s"), psCmd.c_str()) );
+ int result = wxExecute(psCmd, psOutput, psErrors, wxEXEC_SYNC);
+ psCmd.Clear();
+ if (result != 0)
+ { psCmd << wxT("Result of ps x:") << result;
+ DebugLog(wxString::Format( _("Execution Error:"), psCmd.c_str()) );
+ return wxEmptyString;
+ }
+
+ wxString ConsTtyStr;
+ wxString ConsPidStr;
+ ConsPidStr << ConsPid;
+ //find task with our unique sleep time
+ wxString uniqueSleepTimeStr;
+ uniqueSleepTimeStr << wxT("sleep ") << 80000 + ::wxGetProcessId();
+ // search the output of "ps pid" command
+ int knt = psOutput.GetCount();
+ for (int i=knt-1; i>-1; --i)
+ { psCmd = psOutput.Item(i);
+ DebugLog(wxString::Format( _("PS result: %s"), psCmd.c_str()) );
+ // find the pts/# or tty/# or whatever it's called
+ // by seaching the output or out "ps x" command.
+ // The output of ps looks like:
+ // PID TTY STAT TIME COMMAND
+ // 8779 pts/3 Ss+ 0:00 sleep 600000
+ //if (psCmd.Contains(ConsPidStr))
+ if (psCmd.Contains(uniqueSleepTimeStr))
+ { ConsTtyStr = psCmd.Mid( ConsPidStr.Length()+2);
+ ConsTtyStr = wxT("/dev/")+ConsTtyStr.BeforeFirst(' ');
+ DebugLog(wxString::Format( _("TTY is[%s]"), ConsTtyStr.c_str()) );
+ return ConsTtyStr;
+ }//if
+ }//for
+
+ knt = psErrors.GetCount();
+ for (int i=0; i<knt; ++i)
+ DebugLog(wxString::Format( _("PS Error:%s"), psErrors.Item(i).c_str()) );
+ return wxEmptyString;
+}
Index: gdb_driver.h
===================================================================
--- gdb_driver.h (revision 3654)
+++ gdb_driver.h (working copy)
@@ -86,24 +86,24 @@
// Seems to be intended to allow step before program has started.
// Was always false. HC changed to take value from DebuggerGDB::m_BreakOnEntry.
- bool m_BreakOnEntry;
-
+ bool m_BreakOnEntry;
+
// Seems to be used to issue a InfoProgram command, then continue
// True after first "Start()", until first break
- bool m_ManualBreakOnEntry;
+ bool m_ManualBreakOnEntry;
- // Program is "running": after a "run" or a "start", and before "kill" or a "quit"
- bool m_IsStarted;
-
+// // Program is "running": after a "run" or a "start", and before "kill" or a "quit"
+// bool m_IsStarted;
+
// cursor update flags
bool m_needsUpdate;
bool m_forceUpdate;
-
+
// GDB version
long m_GDBVersionMajor;
long m_GDBVersionMinor;
wxString flavour;
-
+
}; // GDB_driver
#endif // GDB_DRIVER_H
Index: debuggerdriver.h
===================================================================
--- debuggerdriver.h (revision 3654)
+++ debuggerdriver.h (working copy)
@@ -132,6 +132,7 @@
/** Is the program stopped? */
virtual bool IsStopped(){ return m_ProgramIsStopped; }
+ virtual bool IsStarted(){ return m_IsStarted; } //(pecan 2007/3/01)
/** Get debugger cursor. */
virtual const Cursor& GetCursor() const { return m_Cursor; }
/** Set child PID (debuggee's). Usually set by debugger commands. */
@@ -162,6 +163,11 @@
// cursor related
bool m_ProgramIsStopped;
+ //(pecan 2007/3/01)
+ // moved here from gdb_driver.h
+ // Program is "running": after a "run" or a "start", and before "kill" or a "quit"
+ bool m_IsStarted;
+ ;
wxString m_LastCursorAddress;
Cursor m_Cursor;
Index: debuggergdb.h
===================================================================
--- debuggergdb.h (revision 3654)
+++ debuggergdb.h (working copy)
@@ -110,6 +110,7 @@
int LaunchProcess(const wxString& cmd, const wxString& cwd);
wxString GetDebuggee(ProjectBuildTarget* target);
bool IsStopped();
+ bool IsStarted(); //(pecan 2007/3/01)
void OnUpdateUI(wxUpdateUIEvent& event);
void OnDebug(wxCommandEvent& event);
@@ -204,7 +205,15 @@
SearchDirsMap m_SearchDirs;
int m_HookId; // project loader hook ID
+ int m_GDBInputKnt;
+ // Linux console support
+ int RunNixConsole();
+ wxString GetConsoleTty(int ConsolePid);
+ bool m_bIsConsole;
+ int m_nConsolePid;
+ wxString m_ConsoleTty;
+
DECLARE_EVENT_TABLE()
};
Index: gdb_driver.cpp
===================================================================
--- gdb_driver.cpp (revision 3654)
+++ gdb_driver.cpp (working copy)
@@ -55,7 +55,7 @@
: DebuggerDriver(plugin),
m_BreakOnEntry(false),
m_ManualBreakOnEntry(false),
- m_IsStarted(false),
+// m_IsStarted(false), //(pecan 2007/3/01)
m_GDBVersionMajor(0),
m_GDBVersionMinor(0)
{