Developer forums (C::B DEVELOPMENT STRICTLY!) > Development
debugger stop button on Linux console pgm crashes CB
Pecan:
The line " m_State.StopDriver();" in debuggergdb.cpp is causing a crash in linux when the user hits the stop debugger button. It clears m_State.m_pDriver which is still being used by the events:
EVT_PIPEDPROCESS_STDOUT(idGDBProcess, DebuggerGDB::OnGDBOutput)
EVT_PIPEDPROCESS_STDERR(idGDBProcess, DebuggerGDB::OnGDBError)
--- Code: ---
void DebuggerGDB::OnGDBTerminated(wxCommandEvent& event)
{
m_PidToAttach = 0;
m_TimerPollDebugger.Stop();
m_LastExitCode = event.GetInt();
//the process deletes itself
// m_pProcess = 0L;
ClearActiveMarkFromAllEditors();
m_State.StopDriver();
Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Debugger finished with status %d"), m_LastExitCode);
if (m_NoDebugInfo)
{
cbMessageBox(_("This project/target has no debugging info."
"Please change this in the project's build options and retry..."),
_("Error"),
wxICON_STOP);
}
// switch to the user-defined layout when finished debugging
DoSwitchLayout(_T("layout_end"));
}
--- End code ---
The crashes stop when that line is commented out. But it causes OnProjectActivated and OnProjectClosed to think the project is still in debugging mode.
Pecan:
I cannot understand this situation. Look at the last line.
The debugger states that "m_State.HasDriver()" is false, yet the call was make anyway. What the hell ???
--- Code: ---Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1231042896 (LWP 5287)]
0xb4641020 in DebuggerDriver::CurrentCommand (this=0x8bf1db8)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggerdriver.cpp:98
98 return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) bt
#0 0xb4641020 in DebuggerDriver::CurrentCommand (this=0x8bf1db8)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggerdriver.cpp:98
#1 0xb4666b37 in GDB_driver::ParseOutput (this=0x8bf1db8, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
#2 0xb464484d in DebuggerGDB::ParseOutput (this=0x8a17918, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1543
#3 0xb4646c8c in DebuggerGDB::OnGDBOutput (this=0x8a17918, event=@0xb3c005c4)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1918
#4 0xb792d655 in wxAppConsole::HandleEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#5 0xb79bcb52 in wxEvtHandler::ProcessEventIfMatches ()
from /usr/lib/libwx_baseu-2.6.so.0
#6 0xb79bcc9d in wxEventHashTable::HandleEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#7 0xb79bce1f in wxEvtHandler::ProcessEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#8 0xb79bd2d0 in wxEvtHandler::ProcessPendingEvents ()
from /usr/lib/libwx_baseu-2.6.so.0
#9 0xb792dbef in wxAppConsole::ProcessPendingEvents ()
from /usr/lib/libwx_baseu-2.6.so.0
#10 0xb770a4dd in Manager::ProcessPendingEvents () at sdk/manager.cpp:108
#11 0xb77c94cf in SimpleTextLog::AddLog (this=0x8b24490, msg=@0xbf917b9c,
addNewLine=true) at sdk/simpletextlog.cpp:70
#12 0xb770f001 in MessageManager::Log (this=0x862afa8, id=6, msg=@0xbf917b9c)
at sdk/messagemanager.cpp:455
#13 0xb4641f8a in DebuggerGDB::DebugLog (this=0x8a17918, msg=@0xbf917b9c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:566
#14 0xb4666af9 in GDB_driver::ParseOutput (this=0x8bf1db8, output=@0xbf917b9c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:613
#15 0xb464484d in DebuggerGDB::ParseOutput (this=0x8a17918, output=@0xbf917b9c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1543
#16 0xb4646c8c in DebuggerGDB::OnGDBOutput (this=0x8a17918, event=@0xb3c00570)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1918
#17 0xb792d655 in wxAppConsole::HandleEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#18 0xb79bcb52 in wxEvtHandler::ProcessEventIfMatches ()
from /usr/lib/libwx_baseu-2.6.so.0
#19 0xb79bcc9d in wxEventHashTable::HandleEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#20 0xb79bce1f in wxEvtHandler::ProcessEvent ()
from /usr/lib/libwx_baseu-2.6.so.0
#21 0xb79bd2d0 in wxEvtHandler::ProcessPendingEvents ()
from /usr/lib/libwx_baseu-2.6.so.0
#22 0xb792dbef in wxAppConsole::ProcessPendingEvents ()
---Type <return> to continue, or q <return> to quit---q
from /usr/lib/libwx_baseQuit
(gdb) f 3
#3 0xb4646c8c in DebuggerGDB::OnGDBOutput (this=0x8a17918, event=@0xb3c005c4)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1918
1918 }
(gdb) p m_state
No symbol "m_state" in current context.
(gdb) p m_State
$1 = {m_pPlugin = 0x8a17918, m_pDriver = 0x0,
m_Watches = {<wxArrayPtrVoid> = {<wxBaseArrayPtrVoid> = {m_nSize = 0,
m_nCount = 0, m_pItems = 0x0}, <No data fields>}, <No data fields>},
m_Breakpoints = {<wxBaseArrayPtrVoid> = {m_nSize = 0, m_nCount = 0,
m_pItems = 0x0}, <No data fields>}, m_BpAutoIndex = 0}
(gdb) f 2
#2 0xb464484d in DebuggerGDB::ParseOutput (this=0x8a17918, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1543
1543 m_State.GetDriver()->ParseOutput(output);
(gdb) p m_State
$2 = {m_pPlugin = 0x8a17918, m_pDriver = 0x0,
m_Watches = {<wxArrayPtrVoid> = {<wxBaseArrayPtrVoid> = {m_nSize = 0,
m_nCount = 0, m_pItems = 0x0}, <No data fields>}, <No data fields>},
m_Breakpoints = {<wxBaseArrayPtrVoid> = {m_nSize = 0, m_nCount = 0,
m_pItems = 0x0}, <No data fields>}, m_BpAutoIndex = 0}
(gdb) f 1
#1 0xb4666b37 in GDB_driver::ParseOutput (this=0x8bf1db8, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
620 DebuggerCmd* cmd = CurrentCommand();
(gdb) p m_State
No symbol "m_State" in current context.
(gdb) f
#1 0xb4666b37 in GDB_driver::ParseOutput (this=0x8bf1db8, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
620 DebuggerCmd* cmd = CurrentCommand();
(gdb) f 0
#0 0xb4641020 in DebuggerDriver::CurrentCommand (this=0x8bf1db8)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggerdriver.cpp:98
98 return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) p m_DCmds
$3 = {<wxBaseArrayPtrVoid> = {m_nSize = 16, m_nCount = 1,
m_pItems = 0x0}, <No data fields>}
(gdb) l
93 RunQueue();
94 }
95
96 DebuggerCmd* DebuggerDriver::CurrentCommand()
97 {
98 return m_DCmds.GetCount() ? m_DCmds[0] : 0;
99 }
100
101 void DebuggerDriver::RunQueue()
102 {
(gdb) up
#1 0xb4666b37 in GDB_driver::ParseOutput (this=0x8bf1db8, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
620 DebuggerCmd* cmd = CurrentCommand();
(gdb) l
615 int idx = buffer.First(GDB_PROMPT);
616 if (idx != wxNOT_FOUND)
617 {
618 m_ProgramIsStopped = true;
619 m_QueueBusy = false;
620 DebuggerCmd* cmd = CurrentCommand();
621 if (cmd)
622 {
623 // Log(_T("Command parsing output: ") + buffer.Left(idx));
624 RemoveTopCommand(false);
(gdb) up
#2 0xb464484d in DebuggerGDB::ParseOutput (this=0x8a17918, output=@0xbf91780c)
at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1543
1543 m_State.GetDriver()->ParseOutput(output);
(gdb) p m_state
No symbol "m_state" in current context.
(gdb) p m_State
$4 = {m_pPlugin = 0x8a17918, m_pDriver = 0x0,
m_Watches = {<wxArrayPtrVoid> = {<wxBaseArrayPtrVoid> = {m_nSize = 0,
m_nCount = 0, m_pItems = 0x0}, <No data fields>}, <No data fields>},
m_Breakpoints = {<wxBaseArrayPtrVoid> = {m_nSize = 0, m_nCount = 0,
m_pItems = 0x0}, <No data fields>}, m_BpAutoIndex = 0}
(gdb) l
1538
1539 void DebuggerGDB::ParseOutput(const wxString& output)
1540 {
1541 if (m_State.HasDriver())
1542 {
1543 m_State.GetDriver()->ParseOutput(output);
1544 }
1545 }
1546
1547 void DebuggerGDB::BringAppToFront()
(gdb) p m_State.HasDriver()
$5 = false
(gdb)
--- End code ---
Pecan:
In the pre-waking hours this morning it finally dawned on me what is going on here.
debuggerGDB m_State variables are being manipulated from two different threads without a critical section.
The message queues and mState.m_pDriver (especially) are being changed while m_pProcess (the PipedProcess) functions:
EVT_PIPEDPROCESS_STDOUT(idGDBProcess, DebuggerGDB::OnGDBOutput)
EVT_PIPEDPROCESS_STDERR(idGDBProcess, DebuggerGDB::OnGDBError)
are also changing the queues and depending on the variables pointed to by m_pDriver, which is being cleared by DebuggerGDB.{Stop()|Cleanup()|StopDriver()}
This explains the crashes and the weird freezes and hangs I often get while debugging, because m_pProcess(PipedProcess) is adding messages while DebuggerGDB and gdb_Driver are removing 'em asynchronously.
This is why the message queue shows it has x number of msgs, but that m_pItems\[x\] are empty.
@Yiannis
Do you want to fix this, or would you care for me to try and find a place to add a wxCriticalSection and see how it goes.
artoj:
Excellent work, thanks Pecan! :)
mandrav:
--- Quote from: pecan ---@Yiannis
Do you want to fix this, or would you care for me to try and find a place to add a wxCriticalSection and see how it goes.
--- End quote ---
Although I have failed to reproduce a crash, I will have a look.
And no threads are used in the debugger plugin AFAIR...
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version