void GDB_driver::ParseOutput(const wxString& output)
{
m_Cursor.changed = false;
// Watch for initial debug info and grab the child PID
// this is put here because we need this info even if
// we don't get a prompt back.
// It's "cheap" anyway because the line we 're after is
// the very first line printed by gdb when running our
// program. It then sets the child PID and never enters here
// again because the "want_debug_events" condition below
// is not satisfied anymore...
if (platform::windows && want_debug_events)
{
wxRegEx* re = 0;
if ((m_GDBVersionMajor > 6 || (m_GDBVersionMajor == 6 && m_GDBVersionMinor >= 7)) &&
output.Contains(_T("CREATE_PROCESS_DEBUG_EVENT")))
{
re = &reChildPid2;
}
else if (m_GDBVersionMajor <= 6 && output.Contains(_T("do_initial_child_stuff")))
re = &reChildPid;
else if (m_attachedToProcess)
re = &reAttachedChildPid;
if (re)
{
// got the line with the PID, parse it out:
// e.g.
// gdb: do_initial_child_stuff: process 1392
if (re->Matches(output))
{
wxString pidStr = re->GetMatch(output, 1);
long pid = 0;
pidStr.ToLong(&pid);
SetChildPID(pid);
want_debug_events = false;
disable_debug_events = true;
m_pDBG->Log(wxString::Format(_("Child process PID: %d"), pid));
}
}
}
else if (!platform::windows && m_ChildPID == 0)
{
if (reChildPid3.Matches(output)) // [Switching to Thread -1234655568 (LWP 18590)]
{
wxString pidStr = reChildPid3.GetMatch(output, 1);
long pid = 0;
pidStr.ToLong(&pid);
SetChildPID(pid);
m_pDBG->Log(wxString::Format(_("Child process PID: %d"), pid));
}
}
if (!want_debug_events &&
(output.StartsWith(_T("gdb: ")) ||
output.StartsWith(_T("Warning: ")) ||
output.StartsWith(_T("ContinueDebugEvent "))))
{
return;
}
static wxString buffer;
buffer << output << _T('\n');
m_pDBG->DebugLog(output);
int idx = buffer.First(GDB_PROMPT);
if (idx == wxNOT_FOUND)
{
// don't uncomment the following line
// m_ProgramIsStopped is set to false in DebuggerDriver::RunQueue()
// m_ProgramIsStopped = false;
return; // come back later
}
if (disable_debug_events)
{
// we don't want debug events anymore (we got the pid)
QueueCommand(new DebuggerCmd(this, _T("set debugevents off")));
disable_debug_events = false;
}
Here is the code to parse gdb output.
To catch the PID, we have different methods:
Under Windows, we need first "set debugevents on", and if we receive some message matches "CREATE_PROCESS_DEBUG_EVENT", then we get the PID, and send: "set debugevents off".
Under Linux, it is quite simple, just matches the message "[Switching to Thread -1234655568 (LWP 18590)]"
When I debug under Windows gdb, I see some message:
Debugger name and version: GNU gdb (GDB) 7.4.50.20120331-cvs
[debug]>>>>>>cb_gdb:
[debug]> set width 0
[debug]>>>>>>cb_gdb:
[debug]> set height 0
[debug]>>>>>>cb_gdb:
[debug]> set breakpoint pending on
[debug]>>>>>>cb_gdb:
[debug]> set print asm-demangle on
[debug]>>>>>>cb_gdb:
[debug]> set unwindonsignal on
[debug]>>>>>>cb_gdb:
[debug]> set print elements 0
[debug]>>>>>>cb_gdb:
[debug]> set debugevents on
[debug]>>>>>>cb_gdb:
[debug]> set disassembly-flavor att
[debug]>>>>>>cb_gdb:
[debug]> catch throw
[debug]Catchpoint 1 (throw)
[debug]>>>>>>cb_gdb:
[debug]> source E:\code\gcc\PCXMinGW463\\bin\my.gdb
[debug]>>>>>>cb_gdb:
[debug]> directory E:/code/cb/test_code/IsAlpha/
[debug]Source directories searched: E:/code/cb/test_code/IsAlpha;$cdir;$cwd
[debug]>>>>>>cb_gdb:
[debug]> break "E:/code/cb/test_code/IsAlpha/IsAlphaMain.cpp:114"
[debug]Breakpoint 2 at 0x401f5c: file E:\code\cb\test_code\IsAlpha\IsAlphaMain.cpp, line 114.
[debug]>>>>>>cb_gdb:
[debug]> break "E:/code/cb/test_code/IsAlpha/IsAlphaMain.cpp:106"
[debug]Breakpoint 3 at 0x401e6b: file E:\code\cb\test_code\IsAlpha\IsAlphaMain.cpp, line 106.
[debug]>>>>>>cb_gdb:
[debug]> run
[debug]Starting program: E:\code\cb\test_code\IsAlpha\bin\Debug\IsAlpha.exe
[debug]gdb: windows_init_thread_list
Child process PID: 2684
[debug][New Thread 2684.0xf40]
[debug]Breakpoint 3, IsAlphaFrame::OnAbout (this=0xb66da0, event=...) at E:\code\cb\test_code\IsAlpha\IsAlphaMain.cpp:106
[debug]E:\code\cb\test_code\IsAlpha\IsAlphaMain.cpp:106:3032:beg:0x401e6b
[debug]>>>>>>cb_gdb:
At E:\code\cb\test_code\IsAlpha\IsAlphaMain.cpp:106
[debug]> set debugevents off
[debug]>>>>>>cb_gdb:
There are two point:
1, the set debugevents off command is send only after the first bp meet.
2, there are some message "[New Thread 2684.0xf40]", and this 2684 is just the PID, so can we simplify use this info to get PID?