From time to time I get the following assert firing when I switch to viewing a new source file. Usually it appears to happen when I hit F11 to switch between .h and .cpp files, I don't have a reproducible set of steps yet; it just seems to happen occassionally.
ASSERT INFO:
../src/common/wincmn.cpp(372): assert "id == wxID_ANY || (id >= 0 && id < 32767) || (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST)" failed in CreateBase(): invalid id value
BACKTRACE:
[1] wxWindowBase::CreateBase(wxWindowBase, int, wxPoint const&, wxSize const&, long, wxString const&)
[2] wxWindowBase::CreateBase(wxWindowBase, int, wxPoint const&, wxSize const&, long, wxValidator const&, wxString const&)
[3] wxWindow::Create(wxWindow, int, wxPoint const&, wxSize const&, long, wxString const&)
[4] wxControl::Create(wxWindow, int, wxPoint const&, wxSize const&, long, wxValidator const&, wxString const&)
[5] wxScintilla::Create(wxWindow, int, wxPoint const&, wxSize const&, long, wxString const&)
[6] wxScintilla::wxScintilla(wxWindow, int, wxPoint const&, wxSize const&, long, wxString const&)
[7] cbStyledTextCtrl::cbStyledTextCtrl(wxWindow, int, wxPoint const&, wxSize const&, long)
[8] cbEditor::CreateEditor()
[9] cbEditor::DoInitializations(wxString const&, LoaderBase)
[10] cbEditor::cbEditor(wxWindow, LoaderBase, wxString const&, EditorColourSet)
[11] EditorManager::Open(LoaderBase, wxString const&, int, ProjectFile)
[12] CompilerErrors::DoGotoError(CompileError const&)
[13] wxAppConsoleBase::CallEventHandler(wxEvtHandler, wxEventFunctor&, wxEvent&) const
[14] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler, wxEvent&)
[15] wxEvtHandler::SearchDynamicEventTable(wxEvent&)
[16] wxEvtHandler::TryHereOnly(wxEvent&)
[17] wxEvtHandler::DoTryChain(wxEvent&)
[18] wxEvtHandler::ProcessEvent(wxEvent&)
[19] wxWindowBase::TryAfter(wxEvent&)
[20] wxWindowBase::TryAfter(wxEvent&)
[21] wxScrollHelperEvtHandler::ProcessEvent(wxEvent&)
[22] wxGenericListCtrl::SetItemState(long, long, long)
[23] CompilerMessages::FocusError(int)
[24] CompilerGCC::OnJobEnd(unsigned long, int)
[25] wxAppConsoleBase::CallEventHandler(wxEvtHandler, wxEventFunctor&, wxEvent&) const
[26] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler, wxEvent&)
[27] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler)
[28] wxEvtHandler::TryHereOnly(wxEvent&)
[29] wxEvtHandler::ProcessEventLocally(wxEvent&)
[30] wxEvtHandler::ProcessEvent(wxEvent&)
[31] wxEvtHandler::ProcessPendingEvents()
[32] wxAppConsoleBase::ProcessPendingEvents()
[33] wxApp::DoIdle()
[34] g_main_context_dispatch
[35] g_main_loop_run
[36] gtk_main
[37] wxGUIEventLoop::DoRun()
[38] wxEventLoopBase::Run()
[39] wxAppConsoleBase::MainLoop()
[40] CodeBlocksApp::OnRun() /home/john/third_party/codeblocks/src/src/app.cpp:852
[41] wxEntry(int&, wchar_t**)
[42] main /home/john/third_party/codeblocks/src/src/app.cpp:322
[43] __libc_start_main
[44] _start
I'm running of a build from trunk two days ago at revision 10527.
Can you reproduce this problem if you disable most of the plugins?
Can you reproduce the problem right after starting codeblocks?
If not can you remember all the things you do until it happens?
The problem seems to be that we're getting out of wxNewIDs...
Can you attach a debugger and tell us what is the value of the id when the assert triggers?
Probably you'll need to build a debug version of codeblocks.
I've seen it happen quite quickly after start up, i.e., within a couple of minutes, so I doubt it's any kind of 'normal' id exhaustion. Other times it takes an hour or more. I disabled the doxygen plugin because it seemed to be calling wxNextId() within headers which the web says is likely a bad idea, but that didn't seem to help.
I still don't have steps to reproduce. I'll work on that. However, on the last assert, the ID was 32843. The whole backtrace follows in case it helps.
Last edit: jmacc 2015-10-06
OK. This is not helpful unfortunately.
One other thing you could do is:
1. Start cb under gdb, open your project, set it up
2. ctrl-c in the gdb prompt
3. break wxNew
4. cont
5. continue doing your normal work with cb
6. just inspect the backtrace every time new id is created
7. if you find some pattern then we'll fix it.
See this http://slackito.com/2011/12/09/poor-mans-tracepoints-with-gdb/ if you want to automate this process.
Also disable as many plugins as possible. If I were you I'd start with the keybinder.
One more thing - are you using context menus a lot?
I use the 'Show file in project tree' context menu quite a bit. I also use 'Swap header / source' constantly, but only via F11 and not via the context menu itself (so I don't know if that counts for the purposes of your question.)
I'll try the gdb thing.
Hey, thanks for the gdb trick. That's pretty neat.
What seems to be happening is that mouse move events over an open source file generate new IDs, so they seem to go up pretty quickly. The source code is this function in ScintillaWX.cpp
(Apparently a timer needs a new id?) I put a breakpoint on wxNewID() and this back trace fires constantly when the mouse is moving.
Is that the problem? Do you need any other info?
Last edit: jmacc 2015-10-07
Here is my obverse and suggest:
In sdk\wxscintilla\src\scintilla\src\Editor.h
enum TickReason { tickCaret, tickScroll, tickWiden, tickDwell, tickPlatform };
And in sdk\wxscintilla\src\ScintillaWX.h
wxTimer* timers[tickDwell+1];
So, we can create an array like above, also, I think they can be static member variables
static int timerIds[tickDwell+1];
Note tested yet.
Firsty, I try to looked at wxWidgts' git repo, and I see it doesn't use several times: wxWidgets/src/stc/ScintillaWX.cpp, so no reference here.
Next, I looked at the official scintilla package: zip format, there are some implementation such as scintillaQT and scintillaGTK.
In QT implemantation, it has:
Sounds like it directly compare the timer id, not the event id, since timers is an int array, since it is initilized like below:
The GTK version use a structure:
while, it just store the "reason" (enum type) as the type, and when time out happens, it just know which timer event is arrived
Now, back to our implemantation, we have such code:
So, my idea which could be much eaiser is that, why not directly compare the "wxTimer"? Since in the wxTimeEvent?
But it looks like we can't the wxTimer pointer from this event, so I think the static timerIds are still good method.
BTW: is it possible to just pass the enum value as the ID?
Nope, we have to pass real ID I think.
Interesting this timer code is not present in the wxSTC in wx-master branch.
@Morten: Can you tell us why do you need this?
@OBF:
See: Scintilla and SciTE
The release of 3.5.0
I think wxSTC just doesn't implement this feature.
Yes, wxSTC is far behind our version. But for the next upgrade they will need to implement something similar, too.
For now, I think ollydbg's proposal is good enough: Limit the ID's for the possible max. number of parallel timers. When the timer is freed, you can also release ID's for re-use or to track if its really not used any longer.
I wasn't aware that this could become a problem when I implemented the function.
(And sorry, just today I read this ticket.)
I think, I'll contact scintilla people first. To see if I can use the same ids/timers for different editors. Because if we allocate N ids per editor, then we'll deplete the id pool after 500-1000 editors are opened closed. And this is not that higher number.
I think using the same ids for different editors are quite safe. But we should use different timers. (we use ids as they are static menber variables, and timers are allocated in heap).
Please test and review the attached patch.
I don't like calling new every time a timer is created thus I've move the code to the constructor/destructor. I doubt it will affect the performance much.
I've applied that patch and have been running the code for a few hours. Normally I would have seen the assert by now, but so far I haven't seen it. I've also seen no adverse affects so far as I can tell.
I've been running the patch for a couple of days now. The asserts are gone. I don't see any new issues.
@Morten: Can you look at the patch to see if I'm not doing something stupid?
My comments: I read your patch days ago, I didn't see any flaws. Good work!
Fix in trunk/master.
@Teodor: Thanks!