Applying to trunk; as of yesterday SVN ???? Not on partition with full SVN Tools. It was updated yesterday sometime.
Tim S.
patch --backup-if-mismatch --unified --strip=0 --ignore-whitespace --forward --input=..\Patches\temp\dbg_speedup-CRLF.patch
patching file src/plugins/compilergcc/compilergcc.cpp
patching file src/plugins/debuggergdb/debuggergdb.cpp
Hunk #1 succeeded at 1035 (offset 394 lines).
patching file src/sdk/pipedprocess.cpp
patching file src/sdk/toolsmanager.cpp
patching file src/include/pipedprocess.h
Hunk #2 succeeded at 35 with fuzz 1.
Maybe this code causes the problem:
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;
}
if (re)
.
.
.
Maybe we should do the splitting here
void DebuggerGDB::ParseOutput(const wxString& output)
{
if (!output.IsEmpty() && m_State.HasDriver())
{
m_State.GetDriver()->ParseOutput(output);
}
}
Can you test?
Do you have sample output from gdb? On linux I've no problems with it.
There is an easy fix you could try (pseudo code below):
void DebuggerGDB::ParseOutput(const wxString& output)
{
if (!output.IsEmpty() && m_State.HasDriver())
{
wxStringArray lines = split(output, '\n');
for(int ii = 0; ii < lines.count(); ++ii)
m_State.GetDriver()->ParseOutput(lines[ii]);
}
}
This one should simulate the old behaviour...
Your code does not work, here is a corrected version (EDIT: I overread that it is pseudo-code, sorry):
void DebuggerGDB::ParseOutput(const wxString& output)
{
if (!output.IsEmpty() && m_State.HasDriver())
{
wxArrayString lines = GetArrayFromString(output, _T('\n'));
for(int i = 0; i < lines.GetCount(); ++i)
m_State.GetDriver()->ParseOutput(lines[i]);
}
}
I'm not sure if it can work reliably.
Can we reach OnGDBOutput, OnGDBError or the OnTimer-function while we are still parsing splitted output ?
If yes we would most likely mess up the order we send the data to the drivers ParseOutput.
Nevertheless, I attach a file containing the output of debugger's debug-log.
I just wrote the output-parameter from ParseOutput into the log.
[attachment deleted by admin]
There is an easy fix you could try (pseudo code below):
I am not sure if this would work. Can you be sure that the lines are complete? What if the first buffer contains 1.5 lines and the second buffer the second half of the second line (0.5 lines)? In that case the parser will not understand the second line of the first buffer and the first line of the second buffer. Thus one response is skipped.
To make it more clear... what I am talking about is a scenario like this:
Pseudo buffer1:
gdb: whatever_message1 what_ever_param1
gdb: whatever_message2
Pseudo buffer2:
Can we reach OnGDBOutput, OnGDBError or the OnTimer-function while we are still parsing splitted output ?
If yes we would most likely mess up the order we send the data to the drivers ParseOutput.
What exactly are you talking about?
Entering OnGDBOutput while we are in ParseOutput or getting OnGDBError, OnGDBOutput, OnTimer in the middle of a result stream?
I think the first is not possible because the messages are in single thread.
And here is an example of the second situation:
>input line1
>input line 2
>error line 1
>input line 3
>error line 2
No, I do not have any documentation about that (except for the wxwidgets docu).
It's just a question.
If it is sure, that we cannot get one of the events while we are processing one of them, there is no problem using this (splitting the messages in debuggergdb's ParseOutput and call the drivers ParseOutput for each line).
It can happen if someone does wxMesssageBox() or shows another modal dialog.
I've tested it with two timers. I don't know if there aren't any other cases where you can send/receive events from the queue inside a handler of another event? In win32 API you could do:
MSG msg;
while(PeekMessage(&msg, windowHandle, 0, 0, PM_REMOVE /*| PM_QS_PAINT*/) == TRUE)
{
TranslateMessage (&msg);
DispatchMessage(&msg);
}
to pop all messages from the queue.
Is there wx equivalent for this piece of code?
I'm thinking of a strategy how to fix this problem, but I don't have much time/energy at the moment :(
No problems here (until now) but I do not have much time for testing on windows at the moment.
Are you talking about the last patch?
What about this kind of solution:
/// in the class declaration
private:
std::deque<wxString> m_lines;
wxString m_timer1, m_timer2;
bool m_in_handler;
/// in the cpp file
void wx_timerDialog::OnTimer(wxTimerEvent& event)
{
m_timer1 = Common(m_timer1 + "t1_line1\nt1_line2\nt1_line3\n");
}
void wx_timerDialog::OnTimer2(wxTimerEvent& event)
{
m_timer2 = Common(m_timer2 + "t2_line1\nt2_line2\n=t2_line3\n");
}
wxString wx_timerDialog::CommonFunc(wxString const &output)
{
if(m_in_handler)
{
int start = 0;
while(1)
{
wxString::size_type pos = output.find('\n', start);
if(pos != wxString::npos)
{
m_lines.push_back(output.substr(start, pos - start));
start = pos + 1;
}
else
break;
}
if(start < output.length())
{
return output.substr(start, output.length() - start);
}
}
else
{
m_in_handler = true;
while(!m_lines.empty())
{
wxString const &s = m_lines.front();
/// do some processing
m_lines.pop_front();
}
m_in_handler = false;
}
}
Any comments and suggestions are welcome.
No, I do not have any documentation about that (except for the wxwidgets docu).
It's just a question.
If it is sure, that we cannot get one of the events while we are processing one of them, there is no problem using this (splitting the messages in debuggergdb's ParseOutput and call the drivers ParseOutput for each line).
It can happen if someone does wxMesssageBox() or shows another modal dialog.
I've tested it with two timers. I don't know if there aren't any other cases where you can send/receive events from the queue inside a handler of another event?
Based on some previous experience with this, I would think that so long as the handler does not invoke blocking operations that pump the message queue (e.g. modal dialogs) you should be ok. Think about the implications if this wasn't true: how could you do any reliable event handling if new events could interrupt and change the state of the app?
I don't think an output line can be split in the middle, and if it can, this might happen in your code and in the original code.
Couldn't a really really long string be split between buffers? I guess this can only happen if you happen to read the output quicker than it is being written by GDB (not impossible, right?). You could reduce the risk of this happening by continuing to read until IsInputAvailable() returns false (though even this may be error prone):
while(process->IsInputAvailable())
{
stdin_stream->Read(buffer,maxchars);
//append buffer to wxstring or whatever
}