Author Topic: FOUND THE CAUSE FOR *ALL* CRASHES!!!  (Read 8685 times)

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
FOUND THE CAUSE FOR *ALL* CRASHES!!!
« on: August 15, 2005, 09:01:18 am »
Guys, this is heavy! Fasten your seatbelts, because the sky's stormy!  :shock:

Here's an exact copy of the linux backtrace of codeblocks.

The main problem on exit right now is an Update UI event in main.cpp.

The function in question is MainFrame::OnEditMenuUpdateUI(wxUpdateUIEvent& event). This method crashes me when i exit. I had tried to put 1,000 of checks to prevent it from accessing illegal data. But it didn't work!  :shock: I even thought gdb was using an old copy!

Guess what. It's not that what happened. Take a look at this (and carry your oxygen tanks because we're gonna dive DEEP!  :? )

Code
#0  0xb7d6f4c1 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#1  0xb7d6f4c8 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#2  0xb7d6f4c8 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#3  0xb7d6f4c8 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#4  0xb7d6f4c8 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#5  0xb7ccbb99 in wxGenericTreeCtrl::SendDeleteEvent ()
   from /usr/lib/libwx_gtk2-2.4.so
#6  0xb7ccbe79 in wxGenericTreeCtrl::Delete () from /usr/lib/libwx_gtk2-2.4.so
#7  0xb7ccbef0 in wxGenericTreeCtrl::DeleteAllItems ()
   from /usr/lib/libwx_gtk2-2.4.so
#8  0xb7ccc514 in wxGenericTreeCtrl::~wxGenericTreeCtrl ()
   from /usr/lib/libwx_gtk2-2.4.so
#9  0xb7a6a760 in ~wxTreeCtrl (this=0x82b3110) at sdk/projectmanager.cpp:115
#10 0xb7a6a7ae in ~PrjTree (this=0x82b3110) at sdk/projectmanager.cpp:45
#11 0xb7a614c8 in ~ProjectManager (this=0x82b0bd0)
    at sdk/projectmanager.cpp:274
#12 0xb7a600f0 in ProjectManager::Free () at sdk/projectmanager.cpp:70
#13 0xb7a3c86d in Manager::Free () at sdk/manager.cpp:77
#14 0x08063b1a in MainFrame::OnApplicationClose (this=0x8123de0,
    event=@0xbfffe4b0) at src/main.cpp:1333
#15 0xb7d6f6e0 in wxEvtHandler::SearchEventTable ()
   from /usr/lib/libwx_gtk2-2.4.so
#16 0xb7d6f51c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#17 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#18 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#19 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#20 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#21 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#22 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#23 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#24 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#25 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#26 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#27 0xb7e2a328 in wxWindowBase::Close () from /usr/lib/libwx_gtk2-2.4.so
#28 0xb7d25ed8 in gtk_frame_delete_callback () from /usr/lib/libwx_gtk2-2.4.so
#29 0xb748dbca in _gtk_marshal_BOOLEAN__BOXED ()
   from /usr/lib/libgtk-x11-2.0.so.0
#30 0xb7258351 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#31 0xb72687e2 in g_signal_emit_by_name () from /usr/lib/libgobject-2.0.so.0
#32 0xb72676ef in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#33 0xb7267b75 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#34 0xb756fa11 in gtk_widget_send_expose () from /usr/lib/libgtk-x11-2.0.so.0
#35 0xb748b71d in gtk_main_do_event () from /usr/lib/libgtk-x11-2.0.so.0
#36 0xb7338b0b in _gdk_events_queue () from /usr/lib/libgdk-x11-2.0.so.0
#37 0xb71ead0f in g_main_depth () from /usr/lib/libglib-2.0.so.0
#38 0xb71ebcb5 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#39 0xb71ebfd7 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#40 0xb71ec21e in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0

(OK here's when things begin getting interesting)

#41 0xb748b31a in gtk_main_iteration () from /usr/lib/libgtk-x11-2.0.so.0
#42 0xb7ce2b15 in wxClipboard::IsSupported () from /usr/lib/libwx_gtk2-2.4.so
#43 0xb78a2903 in ScintillaWX::CanPaste () from /usr/lib/libwx_gtk2_stc-2.4.so
#44 0xb78c8de3 in Editor::WndProc () from /usr/lib/libwx_gtk2_stc-2.4.so
#45 0xb791113c in ScintillaBase::WndProc () from /usr/lib/libwx_gtk2_stc-2.4.so
#46 0xb78a2d6c in ScintillaWX::WndProc () from /usr/lib/libwx_gtk2_stc-2.4.so
#47 0xb78a5a6a in wxStyledTextCtrl::SendMsg ()
   from /usr/lib/libwx_gtk2_stc-2.4.so
#48 0xb78a89b3 in wxStyledTextCtrl::CanPaste ()
   from /usr/lib/libwx_gtk2_stc-2.4.so
#49 0x08065c6a in MainFrame::OnEditMenuUpdateUI (this=0x8123de0,
    event=@0xbfffefa0) at src/main.cpp:1863
#50 0xb7d6f6e0 in wxEvtHandler::SearchEventTable ()
   from /usr/lib/libwx_gtk2-2.4.so
#51 0xb7d6f51c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#52 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#53 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#54 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#55 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#56 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#57 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#58 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#59 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#60 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#61 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#62 0xb7d94caa in wxFrameBase::DoMenuUpdates () from /usr/lib/libwx_gtk2-2.4.so
#63 0xb7d94d39 in wxFrameBase::DoMenuUpdates () from /usr/lib/libwx_gtk2-2.4.so
#64 0xb7d94f47 in wxFrameBase::DoMenuUpdates () from /usr/lib/libwx_gtk2-2.4.so
#65 0xb7d94f7c in wxFrameBase::OnIdle () from /usr/lib/libwx_gtk2-2.4.so
#66 0xb7d6f6e0 in wxEvtHandler::SearchEventTable ()
   from /usr/lib/libwx_gtk2-2.4.so
#67 0xb7d6f51c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#68 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#69 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#70 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#71 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#72 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#73 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#74 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#75 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#76 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#77 0xb7d6f46c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#78 0xb7cd8025 in wxApp::SendIdleEvents () from /usr/lib/libwx_gtk2-2.4.so
#79 0xb7cd80fd in wxApp::SendIdleEvents () from /usr/lib/libwx_gtk2-2.4.so
#80 0xb7cd8173 in wxApp::OnIdle () from /usr/lib/libwx_gtk2-2.4.so
#81 0xb7d6f6e0 in wxEvtHandler::SearchEventTable ()
   from /usr/lib/libwx_gtk2-2.4.so
#82 0xb7d6f51c in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_gtk2-2.4.so
#83 0xb7cd7ef3 in wxApp::ProcessIdle () from /usr/lib/libwx_gtk2-2.4.so
#84 0xb7cd7457 in wxApp::Yield () from /usr/lib/libwx_gtk2-2.4.so
#85 0xb7e173cb in wxYieldIfNeeded () from /usr/lib/libwx_gtk2-2.4.so
#86 0xb7ccd175 in wxGenericTreeCtrl::ScrollTo ()
   from /usr/lib/libwx_gtk2-2.4.so
#87 0xb7ccf577 in wxGenericTreeCtrl::EnsureVisible ()
   from /usr/lib/libwx_gtk2-2.4.so
#88 0xb7a625e0 in ProjectManager::SetProject (this=0x82b0bd0,
    project=0x8543c70, refresh=true) at sdk/projectmanager.cpp:351
#89 0xb7a7e0a4 in WorkspaceLoader::Open (this=0x850d378, filename=@0xbffff7d0)
    at sdk/workspaceloader.cpp:115
#90 0xb7a009a1 in cbWorkspace::Load (this=0x85434e0) at sdk/cbworkspace.cpp:84
#91 0xb7a00602 in cbWorkspace (this=0x85434e0, filename=@0xbffff8a0)
    at sdk/cbworkspace.cpp:57
#92 0xb7a650db in ProjectManager::LoadWorkspace (this=0x82b0bd0,
    filename=@0xbffff8a0) at sdk/projectmanager.cpp:843
#93 0x080571dc in CodeBlocksApp::InitFrame (this=0x80d8658) at src/app.cpp:187
#94 0x0805753a in CodeBlocksApp::OnInit (this=0x80d8658) at src/app.cpp:249
#95 0xb7cd8998 in wxEntry () from /usr/lib/libwx_gtk2-2.4.so
#96 0x08056784 in main (argc=1, argv=0xbffffac4) at src/app.cpp:40

Whew, that was long, wasn't it? Anyway. Check this out. I'll post the relevant stack frames in reverse so you can see what's going on.

Code
#94 0x0805753a in CodeBlocksApp::OnInit (this=0x80d8658) at src/app.cpp:249
#93 0x080571dc in CodeBlocksApp::InitFrame (this=0x80d8658) at src/app.cpp:187
#92 0xb7a650db in ProjectManager::LoadWorkspace (this=0x82b0bd0,
    filename=@0xbffff8a0) at sdk/projectmanager.cpp:843
#91 0xb7a00602 in cbWorkspace (this=0x85434e0, filename=@0xbffff8a0)
    at sdk/cbworkspace.cpp:57
#90 0xb7a009a1 in cbWorkspace::Load (this=0x85434e0) at sdk/cbworkspace.cpp:84
#89 0xb7a7e0a4 in WorkspaceLoader::Open (this=0x850d378, filename=@0xbffff7d0)
    at sdk/workspaceloader.cpp:115
#88 0xb7a625e0 in ProjectManager::SetProject (this=0x82b0bd0,
    project=0x8543c70, refresh=true) at sdk/projectmanager.cpp:351
...
#49 0x08065c6a in MainFrame::OnEditMenuUpdateUI (this=0x8123de0,
    event=@0xbfffefa0) at src/main.cpp:1863
...
#11 0xb7a614c8 in ~ProjectManager (this=0x82b0bd0)
    at sdk/projectmanager.cpp:274
#10 0xb7a6a7ae in ~PrjTree (this=0x82b3110) at sdk/projectmanager.cpp:45
#9  0xb7a6a760 in ~wxTreeCtrl (this=0x82b3110) at sdk/projectmanager.cpp:115

Have you noticed something weird? Well. Turns out that one event handler calls a function (to scroll a tree, for example), and this event handler starts a recursive chain of event handlers which can end up.... in the *same* event handler!

So what happens when MainFrame::OnFileMenuUpdateUI() calls for one of the properties of the wxStyledTextCtrl class? It triggers an event chain! Which can end up on destroying the SAME OBJECT we accessed a line ago!!!  :shock: :shock: :shock: :shock: :shock: :shock:

Code
   canPaste = ed->GetControl()->CanPaste(); // This happens at the beginning of the program
// CanPaste() triggers an event chain which can last about an entire hour, and ends up with the application closing, destroying ed, and actually everything! There's no way to know ed's been destroyed!
   eolMode = ed->GetControl()->GetEOLMode(); // Seg-fault on exit here

I hope that teaches us _NOT_ to do recursive wxYield()'s. We have to redesign the application if we don't want any more crashes. *specially* the UpdateUI() events.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: FOUND THE CAUSE FOR *ALL* CRASHES!!!
« Reply #1 on: August 15, 2005, 01:27:00 pm »
Use wxApp::Yield instead.

bool wxApp::Yield(bool onlyIfNeeded = FALSE);

:)

The documentation says:
Quote
Calling Yield() recursively is normally an error and an assert failure is raised in debug build if such situation is detected. However if the the onlyIfNeeded parameter is TRUE, the method will just silently return FALSE instead.

Unluckily, even then we are not 100% guaranteed not to have recursive calls, since wxWidgets silently calls Yield at the most impossible occasions, too. wxExecute is an example of this.
« Last Edit: August 15, 2005, 01:42:11 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: FOUND THE CAUSE FOR *ALL* CRASHES!!!
« Reply #2 on: August 15, 2005, 09:10:35 pm »
Unfortunately, this is beyond using a WxYield or not.

Take a closer look:

Quote
#41 0xb748b31a in gtk_main_iteration () from
/usr/lib/libgtk-x11-2.0.so.0
#42 0xb7ce2b15 in wxClipboard::IsSupported () from
/usr/lib/libwx_gtk2-2.4.so
#43 0xb78a2903 in ScintillaWX::CanPaste () from
/usr/lib/libwx_gtk2_stc-2.4.so

In Linux, wxYield calls gtk_main_iteration, which is the function that calls the events (INCLUDING UpdateUI events!).

So, check out what happens when in OnEditMenuUpdateUI, we query the editor's CanPaste(). It calls wxClipboard::IsSupported, which triggers a main loop. It's not actually a fault in Code::Blocks, but in wxGTK. Yes, it is a wxGTK bug.

Update: I reported the bug at wxWidgets Sourceforge. Anyway in the meantime, I think that in this particular case, I'l freeze and disable the main window, and do a second-check from the start.
« Last Edit: August 15, 2005, 09:31:04 pm by rickg22 »