Crash on exiting codeblocks. rpt file attached. Crashes in processing wx event to resize the splitter. If I comment out
sdk\xtra_classes.cpp:
void wxSplitPanel::RefreshSplitter(int idtop,int idbottom,int sashPosition)
{
/*
wxWindow *topwin = m_splitter->FindWindowById(idtop);
wxWindow *bottomwin = m_splitter->FindWindowById(idbottom);
int oldsash = m_splitter->GetSashPosition();
m_splitter->Freeze();
if(topwin && topwin->IsShown() && bottomwin && bottomwin->IsShown())
{
m_splitter->SplitHorizontally(topwin,bottomwin);
}
else
{
wxWindow* thewin = 0;
if (topwin && topwin->IsShown())
thewin = topwin;
else if (bottomwin && bottomwin->IsShown())
thewin = bottomwin;
m_splitter->Initialize(thewin);
}
if (sashPosition)
{
m_splitter->SetSashPosition(sashPosition);
}
else
{
if (!m_SplitterConfig.IsEmpty())
m_splitter->SetSashPosition(ConfigManager::Get()->Read(m_SplitterConfig, (long int)150));
else
m_splitter->SetSashPosition(oldsash);
}
m_splitter->Thaw();
*////
}
then no crash on exit. The splitter of course doesn't refresh, but hopefully this isolates it somewhat. Thinking that a refresh event gets queued and then the application thread exits, while wx dll tries to process event on nonexistant splitter. Maybe debug code can be added to that method above to check for nulls.
[attachment deleted by admin]
Hmmmm makes me wonder.
Try enabling the new "crash protection" option on environment settings.
OK, something wrong with the logic involving topwin and bottomwin. Maybe a conditional breakpoint on m_splitter->Initialize(thewin); when topwin==0 or bottomwin==0. Not positive. The following works without crashing though (might not be correct desired code however). Changes marked ///:
void wxSplitPanel::RefreshSplitter(int idtop,int idbottom,int sashPosition)
{
wxWindow *topwin = m_splitter->FindWindowById(idtop);
wxWindow *bottomwin = m_splitter->FindWindowById(idbottom);
if (!topwin || !bottomwin)///
return;///
int oldsash = m_splitter->GetSashPosition();
m_splitter->Freeze();
if(topwin && topwin->IsShown() && bottomwin && bottomwin->IsShown())
{
m_splitter->SplitHorizontally(topwin,bottomwin);
}
else
{
wxWindow* thewin = 0;
if (topwin && topwin->IsShown())
thewin = topwin;
else if (bottomwin && bottomwin->IsShown())
thewin = bottomwin;
m_splitter->Initialize(thewin);
}
if (sashPosition)
{
m_splitter->SetSashPosition(sashPosition);
}
else
{
if (!m_SplitterConfig.IsEmpty())
m_splitter->SetSashPosition(ConfigManager::Get()->Read(m_SplitterConfig, (long int)150));
else
m_splitter->SetSashPosition(oldsash);
}
m_splitter->Thaw();
}
I think that should be
if(!topwin && !bottomwin) return;
Anyway did you check out my post regarding the "crash protection" option?
What does crash protection do? Didn't prevent a crash btw. Same rpt backtrace as well.
yeah !topwin && !bottomwin looks right. problem is that having either of those lines (|| or &&) prevents it from crashing if the splitter is on
the Projects tab, but if the splitter is on the Watches tab, I still get the crash.
edit: actually it can still crash even with the !top/bottomwindow stuff. looks event related. but definately no crashes if I comment out the contents of RefreshSplitter.
The "crash protection" avoids crashes by avoiding objects from being deleted twice. how does it work? Simple, it skips the wxYield() in message manager :lol:.
It happened to me that I would get crashes in an event handler, but that event happened to be triggered BEFORE exiting C::B. Other events deleted the object in the middle of the call, and it would wreak havoc. It costed me many hours to figure out what was going on...
That was the reason to add the switch. Crashes due to mishandled events shouldn't concern us, since they could be fixed by enabling the option (yes, the UI becomes a bit staggering but that's a separate problem). If you get a crash with the "crash protection" enabled, it means the problem is not in the events, but something else.
Quote from: grv575 on August 23, 2005, 07:30:21 PM
yeah !topwin && !bottomwin looks right. problem is that having either of those lines (|| or &&) prevents it from crashing if the splitter is on
the Projects tab, but if the splitter is on the Watches tab, I still get the crash.
That's because the crash is in wxSplitterWindow, _NOT_ SplitPanel. They're different classes, and the watches tab doesn't use splitpanel.
Mind explaining further (a screenshot before exiting perhaps) how to reproduce the bug? I also need a stack trace with the crash protection enabled. Those stacked idle events in the original report don't look good at all...
Screen right before file->close then crash after 1-2 seconds. Enable crash protection, exit, reload, exit - that's what's in this .rpt log.
Btw, same exact behavior with all plugins disabled & code completion disabled.
[attachment deleted by admin]
Isolated it to this line:
sdk\xtra_classes.cpp:56
m_splitter->SetSashPosition(ConfigManager::Get()->Read(m_SplitterConfig, (long int)150));
With that commented out, it does not crash at all.
Maybe m_SplitterConfig is no longer valid and it's reading from memory no longer in the address space.
Edit: breakpoint on line 56 right before the crash. GDB backtrace attached.
[attachment deleted by admin]
More info:
1 - the crash happens before the destructor - wxSplitPanel::~wxSplitPanel() is called
this (original code) crashes:
m_splitter->SetSashPosition(ConfigManager::Get()->Read(m_SplitterConfig, (long int)150));
this does not:
ConfigManager::Get()->Read(m_SplitterConfig, (long int)150);
this does:
if (m_splitter)
m_splitter->SetSashPosition((long int)307); // hard code value
so it can read the config registry key fine (editor/opened_files_tree_height = 307), but setting the sashposition crashes (even though the wxSplitter is not null).
wxSplitterWindow::SetSashPosition
void SetSashPosition(int position, const bool redraw = TRUE)
Sets the sash position.
Parameters
position
The sash position in pixels.
redraw
If TRUE, resizes the panes and redraws the sash and border.
Remarks
Does not currently check for an out-of-range value.
still debugging, but I don't see why it sets the sash position on openfiletree() refresh from the registry on _every_ refresh?
shouldn't this be changed when it is created (splithorizontally(width, height, sashposfromregistry))?
See if this is correct code (attached). Works for me without crashes. Someone on the wxWidgets mailing list hinted at the new wxSplitter being buggy and to set the sash pos in the splithorizontally() function:
bool SplitHorizontally(wxWindow* window1, wxWindow* window2, int sashPosition = 0)
http://lists.wxwidgets.org/archive/wxPython-users/msg04394.html
Have not tested on linux yet.
Btw: with current version of the code, you can try to hardcode it as m_splitter->SetSashPosition((long int)307);
and then play with resizing the window and moving the Projects tab horizontal seperator. It crashes sometimes, not others (depends if resized sashpos > registry value or current sash pos or something once exiting). Looks like it has something to do with this comment in the docs:
wxSplitterWindow::SetSashPosition
...
Remarks
Does not currently check for an out-of-range value.
But I have no idea what that means.
:?
[attachment deleted by admin]
No wonder the bug didn't happen in 2.4.2... please send me a personal message about it, since there's no way (AFAIK) to mark threads as important. I forget things often :(
Quote from: rickg22 on August 24, 2005, 08:11:12 PM
I forget things often :(
I think that has something todo with you're age :P
OK CVS HEAD doesn't have this crash. So might not be worth looking into at this point. (CVS HEAD unicode built according to: http://forums.next.codeblocks.org/index.php/topic,811.0.html)
Well I see some issue here...
Apparently the saving of the sash position is an awful hack. I just fixed it, and made sure it wouldn't crash (null checks nearly everywhere :-P ).
Also, I made sure that the config reading is only done ONCE, so that'd save us a few clock cycles. I'm committing into CVS right now.
Hum, another crash on exit in HEAD and V1 with wx2.6.1 (no unicode), same bug here again about sash position :(
Anyway, I do not understand why event queues are not emptied when closing the application. May the problem be caused by the use of threads or processes? Seems to me that many bug fixes are just ugly hacks, IMHO there's a subtle problem that need to be fixed in C::B core! Any ideas?
I can't wait for the thread pool :wink:
Bug fixes aren't ugly hacks - some new features are (like the auto-hide message pane). Bug fixes are well... patches for the ugly hacks :-P Of course, good fixes involve a complete refactoring of certain modules.
Anyway, It's not that the event queues are not emptied on exit - it's that some event loops become recursive due to the use of wxYield, unless you enable the "crash protection" tweak. But then again, I'm not sure if you have it enabled.
Also, i think some gtk operations trigger a main event loop (not wxwidgets, but gtk's native), and this might mess up event handling (yes, gtk is ugly). Mind posting the backtrace, please?
Oh sorry, I was talking about windows version. Anyway, I expect no crash when I use a program, so I have not set crash protection "feature" which resemble to a ugly hack for me :lol: Can you explain the wxYield problem and its solution or point me to the thread which explain it?
Sorry but I just get bored with the crash on exit, I have seen many of them while bug fixing the wrong imports for quake3 project.
Agree that gtk is ugly but I was thinking: wxWidgets is supposed to handle all the ugly stuff, isn't it?
Error occured on Monday, August 29, 2005 at 19:14:11.
C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.exe caused an Access Violation at location 20776f64 Reading from location 20776f64.
Registers:
eax=20776f64 ebx=01838690 ecx=60571b60 edx=018ec508 esi=605aed60 edi=0022fa70
eip=20776f64 esp=0022f96c ebp=0022f988 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00010202
Call stack:
20776F64
60571BD9 C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.dll:60571BD9 wxSplitPanel::OnUpdateUI(wxUpdateUIEvent&) D:/projects/codeblocks/codeblocks-head/src/sdk/xtra_classes.cpp:94
100A77A8 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:100A77A8 _ZN12wxEvtHandler21ProcessEventIfMatchesERK21wxEventTableEntryBasePS_R7wxEvent
100A7B6C C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:100A7B6C _ZN16wxEventHashTable11HandleEventER7wxEventP12wxEvtHandler
100A8B49 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:100A8B49 _ZN12wxEvtHandler12ProcessEventER7wxEvent
10209ACC C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10209ACC _ZN12wxWindowBase14UpdateWindowUIEl
10106D64 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10106D64 _ZN8wxWindow14OnInternalIdleEv
101828F1 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:101828F1 _ZN9wxAppBase14SendIdleEventsEP8wxWindowR11wxIdleEvent
10182926 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10182926 _ZN9wxAppBase14SendIdleEventsEP8wxWindowR11wxIdleEvent
10182926 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10182926 _ZN9wxAppBase14SendIdleEventsEP8wxWindowR11wxIdleEvent
10182926 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10182926 _ZN9wxAppBase14SendIdleEventsEP8wxWindowR11wxIdleEvent
10182926 C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:10182926 _ZN9wxAppBase14SendIdleEventsEP8wxWindowR11wxIdleEvent
101827EB C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:101827EB _ZN9wxAppBase11ProcessIdleEv
100E872B C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:100E872B _ZN11wxEventLoop3RunEv
1018241E C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:1018241E _ZN9wxAppBase8MainLoopEv
1004318F C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:1004318F _Z14wxUninitializev
100B077C C:\dev\wxWidgets-2.6.1\lib\gcc_dll\wxmsw26_gcc_custom.dll:100B077C _Z7wxEntryP11HINSTANCE__S0_Pci
004077DA C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.exe:004077DA WinMain D:/projects/codeblocks/codeblocks-head/src/src/app.cpp:297
0043BE08 C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.exe:0043BE08
00401236 C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.exe:00401236 __mingw_CRTStartup d:/src/mingw/build/runtime/../../runtime/crt1.c:226
004012A8 C:\personel\projects\codeblocks\codeblocks-head\src\devel\codeblocks.exe:004012A8 WinMainCRTStartup d:/src/mingw/build/runtime/../../runtime/crt1.c:260
77E9893D C:\WINNT\system32\KERNEL32.dll:77E9893D ProcessIdToSessionId
Same results. wx2.61, windows, nonunicode, latest cvs. Two crashes
1. xtra_classes.cpp:94
-- if(w1 && w2 && w1->IsShown() && w2->IsShown())
IsShown() crashes things???
hard to debug as the OnUpdateUI() event fires every time the window is switched to.
2. compileroptionsdlg.cpp:1024
-- void CompilerOptionsDlg::OnAddVarClick(wxCommandEvent& event)
{
--
makes no sense :)
#107 0xfeeefeee in ?? ()
#108 0xfeeefeee in ?? ()
#109 0xfeeefeee in ?? ()
#110 0xfeeefeee in ?? ()
#111 0x00350007 in ?? ()
#112 0x021c07cf in wxInvalidTextCoord ()
#113 0x105181c0 in vtable for wxWindowList ()
---Type <return> to continue, or q <return> to quit---
#114 0x00000000 in ?? () from
#115 0x00000000 in ?? () from
#116 0xbaadf000 in ?? ()
#117 0x00000000 in ?? () from
#118 0x00000000 in ?? () from
#119 0x00000001 in ?? ()
#120 0xabababab in ?? ()
#121 0xabababab in ?? ()
#122 0xfeeefeee in ?? ()
#123 0x00000000 in ?? () from
#124 0x00000000 in ?? () from
#125 0x00070007 in ?? ()
#126 0x021804c8 in CompilerOptionsDlg::OnAddVarClick (this=0x3e0328,
event=@0x3e0328) at plugins/compilergcc/compileroptionsdlg.cpp:1024
Previous frame inner to this frame (corrupt stack?)
[attachment deleted by admin]
The "crash protection" is not an ugly hack,, is how things actually should BE in the first place.
The wxYield() inserted in the message manager _IS_ the ugly hack. (Do a revision graph on messagemanager.cpp, the wxYield shouldn't be there).
So I added the "hack" to precisely prevent errors like this from happening. Events triggered in the wrong time. Getting rid of the infesting wxYield's is much more elegant than adding SANITY_CHECK's all around the code (you can do a grep and see what i mean. That's an ugly hack, too!)
so, please test the crash on exit with the "crash protection" enabled... it gives me the info that I really need. Otherwise, we're getting lots of noise from the backtrace, and that ain't helping.
Heh. I found a double pointer deletion in my code... :P ironically, that was NOT causing the crash. I couldn't determine the cause! :shock: It must be somewhere in the wxWidgets code... but anyway, I found more or less what series of instructions triggered it. (Couldn't say which one exactly), and replaced the code with something much cleaner.
And doesn't crash now! :D
No more crash on exit for me, HEAD non-unicode wx2.6.1
Yeah looks like questionable wxWidgets behavior - it still returns object memory that was already freed or something - those GetWindow() calls should have returned null instead of crashing when trying to call a method on the returned object.
Quote from: grv575
... those GetWindow() calls should have returned null instead of crashing when trying to call a method on the returned object...
no perfect world ...