News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

debugger stop button on Linux console pgm crashes CB

Started by Pecan, February 06, 2007, 07:01:07 PM

Previous topic - Next topic

Pecan

When debugging a linux console program, and I hit the red stop button, CB crashes as follows:


Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1230633296 (LWP 2568)]
0xb46a4fe4 in DebuggerDriver::CurrentCommand (this=0x8cde9e8)
    at plugins/debuggergdb/debuggerdriver.cpp:98
98          return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) bt
#0  0xb46a4fe4 in DebuggerDriver::CurrentCommand (this=0x8cde9e8)
    at plugins/debuggergdb/debuggerdriver.cpp:98
#1  0xb46caa31 in GDB_driver::ParseOutput (this=0x8cde9e8, output=@0xbfc9063c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
#2  0xb46a8811 in DebuggerGDB::ParseOutput (this=0x8a17b90, output=@0xbfc9063c)
    at plugins/debuggergdb/debuggergdb.cpp:1543
#3  0xb46aac39 in DebuggerGDB::OnGDBOutput (this=0x8a17b90, event=@0x8a2ae40)
    at plugins/debuggergdb/debuggergdb.cpp:1916
#4  0xb7991655 in wxAppConsole::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#5  0xb7a20b52 in wxEvtHandler::ProcessEventIfMatches ()
   from /usr/lib/libwx_baseu-2.6.so.0
#6  0xb7a20c9d in wxEventHashTable::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#7  0xb7a20e1f in wxEvtHandler::ProcessEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#8  0xb7a212d0 in wxEvtHandler::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#9  0xb7991bef in wxAppConsole::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#10 0xb776e4dd in Manager::ProcessPendingEvents () at sdk/manager.cpp:108
#11 0xb782d4cf in SimpleTextLog::AddLog (this=0x8b25b58, msg=@0xbfc909cc,
    addNewLine=true) at sdk/simpletextlog.cpp:70
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) f
#0  0xb46a4fe4 in DebuggerDriver::CurrentCommand (this=0x8cde9e8)
    at plugins/debuggergdb/debuggerdriver.cpp:98
98          return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) p m_DCmds
$16 = {<wxBaseArrayPtrVoid> = {m_nSize = 21, m_nCount = 22,
    m_pItems = 0x17}, <No data fields>}
(gdb) Quit
(gdb)


artoj


Pecan

Quote from: artoj on February 06, 2007, 07:18:53 PM
Most likely this one: Bug #10077 DebuggerDriver crashes CB <<- Stop Debugger, close App

I also got a backtrace (the one in my comment).

Thanks, I'll add my backtrace to it and so something about it as soon as I get the Linux console patch in.

Pecan

While I was trying to chase the stop button crash down, I got another type of crash.
Note that m_Cursor has an invalid address. (So did m_DCmds)

(gdb) p m_DCmds
$16 = {<wxBaseArrayPtrVoid> = {m_nSize = 21, m_nCount = 22,
    m_pItems = 0x17}, <No data fields>}
(gdb) Quit
(gdb)

Both crashes are symptomatic in that these are class variables, not heap, and they both reside in debuggerdriver.h

I dont understand how they could be invalid since debuggerdriver doesn't appear to be a dynamic class. At least I haven't found a "new debuggerdriver(...)" statement yet.



// third type of crash
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1231137104 (LWP 1536)]
0xb796b144 in wxStringBase::operator= () from /usr/lib/libwx_baseu-2.6.so.0
(gdb) bt
#0  0xb796b144 in wxStringBase::operator= () from /usr/lib/libwx_baseu-2.6.so.0
#1  0x08073dda in wxString::operator= (this=0x8fc8cf8)
    at /usr/include/wx-2.6/wx/string.h:611
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
#3  0xb4650a28 in GDB_driver::ParseOutput (this=0x8fc8cd0, output=@0xbfa8850c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:811
#4  0xb462d84d in DebuggerGDB::ParseOutput (this=0x89da6f8, output=@0xbfa8850c)
    at plugins/debuggergdb/debuggergdb.cpp:1543
#5  0xb462fc75 in DebuggerGDB::OnGDBOutput (this=0x89da6f8, event=@0x89eb74c)
    at plugins/debuggergdb/debuggergdb.cpp:1916
#6  0xb7916655 in wxAppConsole::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#7  0xb79a5b52 in wxEvtHandler::ProcessEventIfMatches ()
   from /usr/lib/libwx_baseu-2.6.so.0
#8  0xb79a5c9d in wxEventHashTable::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#9  0xb79a5e1f in wxEvtHandler::ProcessEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#10 0xb79a62d0 in wxEvtHandler::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#11 0xb7916bef in wxAppConsole::ProcessPendingEvents ()
---Type <return> to continue, or q <return> to quit---q
from /usr/lib/libwx_baseQuit
(gdb) f 2
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
885                     m_Cursor.file = reBreak.GetMatch( line, 1);
(gdb) p line
$1 = (wxString &) @0xbfa8846c: {<wxStringBase> = {static npos = 4294967295,
    m_pchData = 0x902ea0c}, <No data fields>}
(gdb) x/s10 line.m_pchData
A syntax error in expression, near `line.m_pchData'.
(gdb) x/10s  line.m_pchData
0x902ea0c:       "\032"
0x902ea0e:       ""
0x902ea0f:       ""
0x902ea10:       "\032"
0x902ea12:       ""
0x902ea13:       ""
0x902ea14:       "/"
0x902ea16:       ""
0x902ea17:       ""
0x902ea18:       "h"
(gdb) x/20s  line.m_pchData
0x902ea0c:       "\032"
0x902ea0e:       ""
0x902ea0f:       ""
0x902ea10:       "\032"
0x902ea12:       ""
0x902ea13:       ""
0x902ea14:       "/"
0x902ea16:       ""
0x902ea17:       ""
0x902ea18:       "h"
0x902ea1a:       ""
0x902ea1b:       ""
0x902ea1c:       "o"
0x902ea1e:       ""
0x902ea1f:       ""
0x902ea20:       "m"
0x902ea22:       ""
0x902ea23:       ""
0x902ea24:       "e"
0x902ea26:       ""
(gdb) x/20c  line.m_pchData
0x902ea0c:      26 '\032'       0 '\0'  0 '\0'  0 '\0'  26 '\032'       0 '\0' 0 '\0'   0 '\0'
0x902ea14:      47 '/'  0 '\0'  0 '\0'  0 '\0'  104 'h' 0 '\0'  0 '\0'  0 '\0'
0x902ea1c:      111 'o' 0 '\0'  0 '\0'  0 '\0'
(gdb) f
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
885                     m_Cursor.file = reBreak.GetMatch( line, 1);
(gdb) p m_Cursor
$2 = {file = {<wxStringBase> = {static npos = 4294967295,
      m_pchData = 0x75}, <No data fields>}, address = {<wxStringBase> = {
      static npos = 4294967295, m_pchData = 0x67}, <No data fields>},
  function = {<wxStringBase> = {static npos = 4294967295,
      m_pchData = 0x67}, <No data fields>}, line = 105, changed = 110}
(gdb)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1231137104 (LWP 1536)]
0xb796b144 in wxStringBase::operator= () from /usr/lib/libwx_baseu-2.6.so.0
(gdb) bt
#0  0xb796b144 in wxStringBase::operator= () from /usr/lib/libwx_baseu-2.6.so.0
#1  0x08073dda in wxString::operator= (this=0x8fc8cf8)
    at /usr/include/wx-2.6/wx/string.h:611
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
#3  0xb4650a28 in GDB_driver::ParseOutput (this=0x8fc8cd0, output=@0xbfa8850c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:811
#4  0xb462d84d in DebuggerGDB::ParseOutput (this=0x89da6f8, output=@0xbfa8850c)
    at plugins/debuggergdb/debuggergdb.cpp:1543
#5  0xb462fc75 in DebuggerGDB::OnGDBOutput (this=0x89da6f8, event=@0x89eb74c)
    at plugins/debuggergdb/debuggergdb.cpp:1916
#6  0xb7916655 in wxAppConsole::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#7  0xb79a5b52 in wxEvtHandler::ProcessEventIfMatches ()
   from /usr/lib/libwx_baseu-2.6.so.0
#8  0xb79a5c9d in wxEventHashTable::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#9  0xb79a5e1f in wxEvtHandler::ProcessEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#10 0xb79a62d0 in wxEvtHandler::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#11 0xb7916bef in wxAppConsole::ProcessPendingEvents ()
---Type <return> to continue, or q <return> to quit---q
from /usr/lib/libwx_baseQuit
(gdb) f 2
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
885                     m_Cursor.file = reBreak.GetMatch( line, 1);
(gdb) p line
$1 = (wxString &) @0xbfa8846c: {<wxStringBase> = {static npos = 4294967295,
    m_pchData = 0x902ea0c}, <No data fields>}
(gdb) x/s10 line.m_pchData
A syntax error in expression, near `line.m_pchData'.
(gdb) x/10s  line.m_pchData
0x902ea0c:       "\032"
0x902ea0e:       ""
0x902ea0f:       ""
0x902ea10:       "\032"
0x902ea12:       ""
0x902ea13:       ""
0x902ea14:       "/"
0x902ea16:       ""
0x902ea17:       ""
0x902ea18:       "h"
(gdb) x/20s  line.m_pchData
0x902ea0c:       "\032"
0x902ea0e:       ""
0x902ea0f:       ""
0x902ea10:       "\032"
0x902ea12:       ""
0x902ea13:       ""
0x902ea14:       "/"
0x902ea16:       ""
0x902ea17:       ""
0x902ea18:       "h"
0x902ea1a:       ""
0x902ea1b:       ""
0x902ea1c:       "o"
0x902ea1e:       ""
0x902ea1f:       ""
0x902ea20:       "m"
0x902ea22:       ""
0x902ea23:       ""
0x902ea24:       "e"
0x902ea26:       ""
(gdb) x/20c  line.m_pchData
0x902ea0c:      26 '\032'       0 '\0'  0 '\0'  0 '\0'  26 '\032'       0 '\0' 0 '\0'   0 '\0'
0x902ea14:      47 '/'  0 '\0'  0 '\0'  0 '\0'  104 'h' 0 '\0'  0 '\0'  0 '\0'
0x902ea1c:      111 'o' 0 '\0'  0 '\0'  0 '\0'
(gdb) f
#2  0xb464e9f5 in GDB_driver::HandleMainBreakPoint (this=0x8fc8cd0,
    reBreak=@0xb467f998, line=@0xbfa8846c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:885
885                     m_Cursor.file = reBreak.GetMatch( line, 1);
(gdb) p m_Cursor
$2 = {file = {<wxStringBase> = {static npos = 4294967295,
      m_pchData = 0x75}, <No data fields>}, address = {<wxStringBase> = {
      static npos = 4294967295, m_pchData = 0x67}, <No data fields>},
  function = {<wxStringBase> = {static npos = 4294967295,
      m_pchData = 0x67}, <No data fields>}, line = 105, changed = 110}
(gdb)

(gdb) p m_Cursor.file
$3 = {<wxStringBase> = {static npos = 4294967295,
    m_pchData = 0x75}, <No data fields>}
(gdb) Quit
(gdb)




Edit: Looks like both got to GDB_driver::ParseOutput by way of
DebuggerGDB::ParseOutput which depends on m_State.GetDrive()


void DebuggerGDB::ParseOutput(const wxString& output)
{
    if (m_State.HasDriver())
    {
        m_State.GetDriver()->ParseOutput(output);
    }
}



My guess is that somehow, GetDriver is returning an incorrect addr.



Pecan

Looks like m_State.m_pDriver is 0x0 when ParseOutput is called.


Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1230625104 (LWP 2242)]
0xb46a7020 in DebuggerDriver::CurrentCommand (this=0x914f728)
    at plugins/debuggergdb/debuggerdriver.cpp:98
98          return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) bt
#0  0xb46a7020 in DebuggerDriver::CurrentCommand (this=0x914f728)
    at plugins/debuggergdb/debuggerdriver.cpp:98
#1  0xb46ccb07 in GDB_driver::ParseOutput (this=0x914f728, output=@0xbfcdc3cc)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:620
#2  0xb46aa84d in DebuggerGDB::ParseOutput (this=0x8a17bc8, output=@0xbfcdc3cc)
    at plugins/debuggergdb/debuggergdb.cpp:1543
#3  0xb46acc75 in DebuggerGDB::OnGDBOutput (this=0x8a17bc8, event=@0xb3c005c4)
    at plugins/debuggergdb/debuggergdb.cpp:1916
#4  0xb7993655 in wxAppConsole::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#5  0xb7a22b52 in wxEvtHandler::ProcessEventIfMatches ()
   from /usr/lib/libwx_baseu-2.6.so.0
#6  0xb7a22c9d in wxEventHashTable::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#7  0xb7a22e1f in wxEvtHandler::ProcessEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#8  0xb7a232d0 in wxEvtHandler::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#9  0xb7993bef in wxAppConsole::ProcessPendingEvents ()
   from /usr/lib/libwx_baseu-2.6.so.0
#10 0xb77704dd in Manager::ProcessPendingEvents () at sdk/manager.cpp:108
#11 0xb782f4cf in SimpleTextLog::AddLog (this=0x8b24788, msg=@0xbfcdc75c,
    addNewLine=true) at sdk/simpletextlog.cpp:70
#12 0xb7775001 in MessageManager::Log (this=0x860acc0, id=6, msg=@0xbfcdc75c)
    at sdk/messagemanager.cpp:455
#13 0xb46a7f8a in DebuggerGDB::DebugLog (this=0x8a17bc8, msg=@0xbfcdc75c)
    at plugins/debuggergdb/debuggergdb.cpp:566
#14 0xb46ccac9 in GDB_driver::ParseOutput (this=0x914f728, output=@0xbfcdc75c)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/gdb_driver.cpp:613
#15 0xb46aa84d in DebuggerGDB::ParseOutput (this=0x8a17bc8, output=@0xbfcdc75c)
    at plugins/debuggergdb/debuggergdb.cpp:1543
#16 0xb46acc75 in DebuggerGDB::OnGDBOutput (this=0x8a17bc8, event=@0xb3c00474)
    at plugins/debuggergdb/debuggergdb.cpp:1916
#17 0xb7993655 in wxAppConsole::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#18 0xb7a22b52 in wxEvtHandler::ProcessEventIfMatches ()
   from /usr/lib/libwx_baseu-2.6.so.0
#19 0xb7a22c9d in wxEventHashTable::HandleEvent ()
   from /usr/lib/libwx_baseu-2.6.so.0
#20 0xb7a22e1f in wxEvtHandler::ProcessEvent ()
---Type <return> to continue, or q <return> to quit---q
from /usr/lib/libwx_baseu-2.6.soQuit
(gdb) f
#0  0xb46a7020 in DebuggerDriver::CurrentCommand (this=0x914f728)
    at plugins/debuggergdb/debuggerdriver.cpp:98
98          return m_DCmds.GetCount() ? m_DCmds[0] : 0;
(gdb) p m_DCmds
$1 = {<wxBaseArrayPtrVoid> = {m_nSize = 16, m_nCount = 1,
    m_pItems = 0x0}, <No data fields>}
(gdb) p m_DCmds[0]
$2 = (_wxArrayDebuggerCommands &) @0x0: Cannot access memory at address 0x0
(gdb) f 2
#2  0xb46aa84d in DebuggerGDB::ParseOutput (this=0x8a17bc8, output=@0xbfcdc3cc)
    at plugins/debuggergdb/debuggergdb.cpp:1543
1543            m_State.GetDriver()->ParseOutput(output);
(gdb) f
#2  0xb46aa84d in DebuggerGDB::ParseOutput (this=0x8a17bc8, output=@0xbfcdc3cc)
    at plugins/debuggergdb/debuggergdb.cpp:1543
1543            m_State.GetDriver()->ParseOutput(output);
(gdb) p m_State
$3 = {m_pPlugin = 0x8a17bc8, [b]m_pDriver = 0x0,[/b]
  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) p output
$4 = (const wxString &) @0xbfcdc3cc: {<wxStringBase> = {
    static npos = 4294967295, m_pchData = 0x903b844}, <No data fields>}
(gdb)




Even tho stop has already occured, and m_State is cleared, DebuggerGDB::OnGDBOutput is trying to parse the message:
"Error detected on stdin".

We either have to drain stdin before destroying m_State, or disconnect it somehow.


(gdb) f 6
#6  0xb46bdc75 in DebuggerGDB::OnGDBOutput (this=0x8a17918, event=@0x8a29a74)
    at /home/pecan/devel/trunk/src/plugins/debuggergdb/debuggergdb.cpp:1916
1916            ParseOutput(msg);
(gdb) l
1911    {
1912        wxString msg = event.GetString();
1913        if (!msg.IsEmpty())
1914        {
1915    //        Manager::Get()->GetMessageManager()->Log(m_PageIndex, _T("O>>> %s"), msg.c_str());
1916            ParseOutput(msg);
1917        }
1918    }
1919
1920    void DebuggerGDB::OnGDBError(wxCommandEvent& event)
(gdb) p msg
$7 = {<wxStringBase> = {static npos = 4294967295,
    m_pchData = 0x90baa14}, <No data fields>}

(gdb) x/80s msg.m_pchData
0x90baa14:       "e"
0x90baa16:       ""
0x90baa17:       ""
0x90baa18:       "r"
0x90baa1a:       ""
0x90baa1b:       ""
0x90baa1c:       "r"
0x90baa1e:       ""
0x90baa1f:       ""
0x90baa20:       "o"
0x90baa22:       ""
0x90baa23:       ""
0x90baa24:       "r"
0x90baa26:       ""
0x90baa27:       ""
0x90baa28:       " "
0x90baa2a:       ""
0x90baa2b:       ""
0x90baa2c:       "d"
0x90baa2e:       ""
0x90baa2f:       ""
0x90baa30:       "e"
0x90baa32:       ""
0x90baa33:       ""
0x90baa34:       "t"
0x90baa36:       ""
0x90baa37:       ""
0x90baa38:       "e"
0x90baa3a:       ""
0x90baa3b:       ""
0x90baa3c:       "c"
0x90baa3e:       ""
0x90baa3f:       ""
0x90baa40:       "t"
0x90baa42:       ""
0x90baa43:       ""
0x90baa44:       "e"
0x90baa46:       ""
0x90baa47:       ""
0x90baa48:       "d"
---Type <return> to continue, or q <return> to quit---
0x90baa4a:       ""
0x90baa4b:       ""
0x90baa4c:       " "
0x90baa4e:       ""
0x90baa4f:       ""
0x90baa50:       "o"
0x90baa52:       ""
0x90baa53:       ""
0x90baa54:       "n"
0x90baa56:       ""
0x90baa57:       ""
0x90baa58:       " "
0x90baa5a:       ""
0x90baa5b:       ""
0x90baa5c:       "s"
0x90baa5e:       ""
0x90baa5f:       ""
0x90baa60:       "t"
0x90baa62:       ""
0x90baa63:       ""
0x90baa64:       "d"
0x90baa66:       ""
0x90baa67:       ""
0x90baa68:       "i"
0x90baa6a:       ""
0x90baa6b:       ""
0x90baa6c:       "n"
0x90baa6e:       ""
0x90baa6f:       ""
0x90baa70:       ""
0x90baa71:       ""
0x90baa72:       ""
0x90baa73:       ""
0x90baa74:       ""
0x90baa75:       ""
0x90baa76:       ""
0x90baa77:       ""
0x90baa78:       ""
0x90baa79:       ""
0x90baa7a:       ""
(

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)






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"));
}



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 ???


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)


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


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.

Although I have failed to reproduce a crash, I will have a look.
And no threads are used in the debugger plugin AFAIR...
Be patient!
This bug will be fixed soon...

Pecan

#10
Quote from: mandrav on February 07, 2007, 02:26:03 PM
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.

Although I have failed to reproduce a crash, I will have a look.
And no threads are used in the debugger plugin AFAIR...


     m_pProcess = new PipedProcess((void**)&m_pProcess, this, idGDBProcess, true, cwd);
    Manager::Get()->GetMessageManager()->AppendLog(m_PageIndex, _("Starting debugger: "));
    m_Pid = wxExecute(cmd, wxEXEC_ASYNC, m_pProcess);


Arn't the above lines creating an asynchronous process that enters DebuggerGDB via OnGDBOutput and OnGDBError as if they are a separate thread?

The GDB traces would suggest that.

mandrav

Quote from: pecanArn't the above lines creating an asynchronous process that enters DebuggerGDB via OnGDBOutput and OnGDBError as if they are a separate thread?

Technically, no, a separate process is not a different thread.
Let me have a look at your findings though.
Be patient!
This bug will be fixed soon...

Pecan

#12
Here is a little console pgm that will crash ever time you hit the Stop button.


#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

int upstring(char *value);


int main()
{
        char value[81]={'\0'};
        int upper_count;
        do
    {   cout << "Please type in a String (max. 80 characters): ";
        cin.getline(value, 80);
        upper_count = upstring(value);
        cout << upper_count << " characters are converted" << endl;
        cout << "The new string is now: " << value << endl;
    }while(upper_count);

  return EXIT_SUCCESS;
}

int upstring(char *value)
{
  int i=0;
  while(*value)
  {
    if(islower(*value))
    {
      *value=toupper(*value);
      i++;
    }
  value++;
  }
  return(i);
}                                                           

Pecan

Quote from: mandrav on February 07, 2007, 02:56:56 PM
Quote from: pecanArn't the above lines creating an asynchronous process that enters DebuggerGDB via OnGDBOutput and OnGDBError as if they are a separate thread?

Technically, no, a separate process is not a different thread.
Let me have a look at your findings though.

Ok, I take it back. It's a process acting just like a thread.
Smells like a duck.....

Pecan

#14
Until Yiannis comes up with a better and more informed patch, here's a patch that fixes the debugger Stop Button crash on Linux.


Index: debuggergdb.cpp
===================================================================
--- debuggergdb.cpp (revision 3558)
+++ debuggergdb.cpp (working copy)
@@ -1503,6 +1503,7 @@

void DebuggerGDB::Stop()
{
+    // m_pProcess is PipedProcess, m_Pid is GDBdebugger
     if (m_pProcess && m_Pid)
     {
         if (IsStopped())
@@ -1534,6 +1535,18 @@
         #endif
         }
     }
+   #if defined(__WXGTK__) //(pecan 2007/2/08)
+    // When PipedProcess and GDB are gone, we can finally
+    // release the GDB_driver
+    if ( !m_pProcess )
+    {
+        if (m_Pid>0)
+         wxKill (m_Pid, wxSIGTERM);
+        m_Pid = 0;
+        m_State.StopDriver();
+    }
+   #endif
+
}

void DebuggerGDB::ParseOutput(const wxString& output)
@@ -1937,7 +1950,17 @@
//    m_pProcess = 0L;

     ClearActiveMarkFromAllEditors();
+
+   #if defined(__WXGTK__)
+    //(pecan 2007/2/07)
+    // Calling m_State.StopDriver() from here causes crashes since
+    // OnGDBOutput() has stacked multiple messages in the system.
+    // and needs the GDB_driver address.
+    //-m_State.StopDriver();
+   #else
     m_State.StopDriver();
+   #endif
+
     Manager::Get()->GetMessageManager()->Log(m_PageIndex, _("Debugger finished with status %d"), m_LastExitCode);

     if (m_NoDebugInfo)
@@ -2056,6 +2079,10 @@
     // allow others to catch this
     event.Skip();

+    #if defined(__WXGTK__)
+     Stop(); //(pecan 2007/2/08)
+    #endif
+
     // when a project is activated and it's not the actively debugged project,
     // ask the user to end debugging or re-activate the debugged project.

@@ -2064,6 +2091,13 @@

     if (event.GetProject() != m_pProject)
     {
+       #if defined(__WXGTK__) //(pecan 2007/2/08)
+        InfoWindow::Display(wxT("Warning"),
+                wxT("You changed the active project while the debugger was active\n"
+                "Debugging will terminate."),
+                6000, 1);
+
+       #else
         wxString msg = _("You can't change the active project while you 're actively debugging another.\n"
                         "Do you want to stop debugging?\n\n"
                         "Click \"Yes\" to stop debugging now or click \"No\" to re-activate the debuggee.");
@@ -2075,6 +2109,7 @@
         {
             Manager::Get()->GetProjectManager()->SetProject(m_pProject);
         }
+        #endif
     }
}

@@ -2083,6 +2118,10 @@
     // allow others to catch this
     event.Skip();

+    #if defined(__WXGTK__)
+     Stop(); //(pecan 2007/2/08)
+    #endif
+
     // remove all search dirs sotred for this project so we don't have conflicts
     // if a newly opened project happens to use the same memory address
     GetSearchDirs(event.GetProject()).clear();
@@ -2100,11 +2139,17 @@

     if (event.GetProject() == m_pProject)
     {
+       #if defined(__WXGTK__) //(pecan 2007/2/08)
+        InfoWindow::Display( wxT("Warning"), _("The project you were debugging has closed.\n"
+                         "The debugging session will terminate immediately."),
+                         6000, 1);
+       #else
         cbMessageBox(_("The project you were debugging has closed.\n"
                         "The debugging session will terminate immediately."),
                     _("Warning"),
                     wxICON_WARNING);
         Stop();
+       #endif
     }
}




The result of all this is that the GDB_driver was being deleted while OnGDBOutput() still had about 5 GDB messages stackup up and being processed.

The delete in OnGDBTerminate() was swiping m_pDriver right out from under an active ParseOutput().