Developer forums (C::B DEVELOPMENT STRICTLY!) > Development

LINUX: Tools Run Crash and Company...

<< < (5/9) > >>

moloh:
I changed wxTimer m_Timer into wxTimer *m_Timer in source code, add suitable new and delete with parameters as in current source. Result? Crash, but different valgrind output. I don't have idea what is happennig, also why this OnToolTerminated is called more that once?

--- Code: ---==29363== Invalid read of size 4
==29363==    at 0x41D56CA: ToolsManager::OnToolTerminated(CodeBlocksEvent&) (toolsmanager.cpp:405)
==29363==    by 0x49AE417: wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3D952: wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DB16: wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DC33: wxEvtHandler::ProcessEvent(wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DEA6: wxEvtHandler::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x49AE9C8: wxAppConsole::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x473E718: (within /usr/lib/libwx_gtk2u_core-2.6.so.0.3.1)
==29363==    by 0x51064AF: (within /usr/lib/libglib-2.0.so.0.800.6)
==29363==  Address 0x61963D4 is 0 bytes after a block of size 108 alloc'd
==29363==    at 0x401CC31: operator new(unsigned) (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==29363==    by 0x416483B: Manager::GetToolsManager() const (manager.h:139)
==29363==    by 0x8090F83: MainFrame::CreateMenubar() (main.cpp:673)
==29363==    by 0x8091DEB: MainFrame::CreateIDE() (main.cpp:537)
==29363==    by 0x8092A9E: MainFrame::MainFrame(wxWindow*) (main.cpp:458)
==29363==    by 0x8065CE8: CodeBlocksApp::InitFrame() (app.cpp:246)
==29363==    by 0x8066A56: CodeBlocksApp::OnInit() (app.cpp:405)
==29363==    by 0x8067A10: wxAppConsole::CallOnInit() (app.h:87)
==29363==    by 0x49E4151: wxEntry(int&, wchar_t**) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4BBC420: (below main) (in /lib/libc-2.3.6.so)
==29363==
==29363== Invalid read of size 4
==29363==    at 0x41D56CD: ToolsManager::OnToolTerminated(CodeBlocksEvent&) (toolsmanager.cpp:405)
==29363==    by 0x49AE417: wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3D952: wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DB16: wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DC33: wxEvtHandler::ProcessEvent(wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x4A3DEA6: wxEvtHandler::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x49AE9C8: wxAppConsole::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==29363==    by 0x473E718: (within /usr/lib/libwx_gtk2u_core-2.6.so.0.3.1)
==29363==    by 0x51064AF: (within /usr/lib/libglib-2.0.so.0.800.6)
==29363==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

--- End code ---
toolsmanager.cpp
405:    m_Timer->Stop();
Error line is with m_Timer pointer but i rather think error is about "this" pointer, not m_Timer. And additionally, why there are two errors there?
To test it i add a NULL check, and to result show it clearly, problem is with "this" pointer, so either bad object is registered somewhere as an event reciver or some other bad thing is happening. But i have no experience how exactly events in wxWidgets work. Here is output

--- Code: ---==9271== Invalid read of size 4
==9271==    at 0x41D56C6: ToolsManager::OnToolTerminated(CodeBlocksEvent&) (toolsmanager.cpp:405)
==9271==    by 0x49AE417: wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3D952: wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DB16: wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DC33: wxEvtHandler::ProcessEvent(wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DEA6: wxEvtHandler::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x49AE9C8: wxAppConsole::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x473E718: (within /usr/lib/libwx_gtk2u_core-2.6.so.0.3.1)
==9271==    by 0x51064AF: (within /usr/lib/libglib-2.0.so.0.800.6)
==9271==  Address 0x5C00BA4 is 0 bytes after a block of size 108 alloc'd
==9271==    at 0x401CC31: operator new(unsigned) (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==9271==    by 0x416483B: Manager::GetToolsManager() const (manager.h:139)
==9271==    by 0x8090F83: MainFrame::CreateMenubar() (main.cpp:673)
==9271==    by 0x8091DEB: MainFrame::CreateIDE() (main.cpp:537)
==9271==    by 0x8092A9E: MainFrame::MainFrame(wxWindow*) (main.cpp:458)
==9271==    by 0x8065CE8: CodeBlocksApp::InitFrame() (app.cpp:246)
==9271==    by 0x8066A56: CodeBlocksApp::OnInit() (app.cpp:405)
==9271==    by 0x8067A10: wxAppConsole::CallOnInit() (app.h:87)
==9271==    by 0x49E4151: wxEntry(int&, wchar_t**) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4BBC420: (below main) (in /lib/libc-2.3.6.so)
==9271==
==9271== Invalid read of size 4
==9271==    at 0x41D56CD: ToolsManager::OnToolTerminated(CodeBlocksEvent&) (toolsmanager.cpp:406)
==9271==    by 0x49AE417: wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3D952: wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DB16: wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DC33: wxEvtHandler::ProcessEvent(wxEvent&) (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x4A3DEA6: wxEvtHandler::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x49AE9C8: wxAppConsole::ProcessPendingEvents() (in /usr/lib/libwx_baseu-2.6.so.0.3.1)
==9271==    by 0x473E718: (within /usr/lib/libwx_gtk2u_core-2.6.so.0.3.1)
==9271==    by 0x51064AF: (within /usr/lib/libglib-2.0.so.0.800.6)
==9271==  Address 0xFFF7993F is not stack'd, malloc'd or (recently) free'd

--- End code ---
toolsmanager.cpp
405:    if( m_Timer )
406:      m_Timer->Stop();

There is also one more question, why in case of m_Timer commenting out (only in source code file, in header there was still declaration of object) things work ok.
I will still try to investigate more this problem, but hope for a help from experienced developer.

moloh:

--- Quote from: moloh on May 25, 2006, 04:19:02 am ---There is also one more question, why in case of m_Timer commenting out (only in source code file, in header there was still declaration of object) things work ok.

--- End quote ---

So it seems things don't work ok.
Under valgrind there are also invalid reads but application does not crash so it seems it is problem with event handling.

Ceniza:
Finally I had the time to look at it and the timer just makes no sense.

The tools manager used to launch the tools in another way which maybe needed this timer to get Code::Blocks responsive, but every launching option is executed asynchronously, so Code::Blocks shouldn't need it now.

It looks like a problem similar to that we had with wxYield before, but it just shouldn't happen, even though it does.

Well, time to remove some code :D

moloh:

--- Quote from: Ceniza on May 26, 2006, 08:53:26 pm ---Well, time to remove some code :D

--- End quote ---

Thanks to removal of wxTimer, codeblocks no longer crash on Tools usage, but problem is still there.
I tried to analyze source code, how event is registered and added some checks. As i said there is problem with this pointer and to check this i add sth like this (all modifications in files toolsmanager.cpp and pipedprocess.cpp, all that are in the post are from toolsmanager.cpp file)

--- Code: ---Manager::Get()->GetMessageManager()->Log(_T("This at start: %d"), this);

--- End code ---
in function that runs Tool (bool ToolsManager::Execute(Tool* tool)) and

--- Code: ---Manager::Get()->GetMessageManager()->Log(_T("This at end: %d"), this);

--- End code ---
in (void ToolsManager::OnToolTerminated(CodeBlocksEvent& event))
As i thought this value is different, why? Ok lets go further...

I added similar modifications to PipedProcess class (there i used m_Parent, which should be the same) and results were pretty interesting.
So it occur to me that problem was that: this pointer is okay in ToolsManger, but bad in ProcessManager...
I googled a moment... and? Here is why: http://carcino.gen.nz/tech/cpp/multiple_inheritance_this.php#downcasting
Read it and You would know (better whole, not only about downcasting).
Problematic line:

--- Code: ---162:    m_pProcess = new PipedProcess((void**)&m_pProcess, this, idToolProcess, pipe, dir);
// comment: i must say this is interesting hack for setting m_Process value, modify self pointer in parent from self, child instance.

--- End code ---
DOWNCASTING OF THIS!!!!!!!!
I am definetly a c programmer, don't know c++ hacks and tricks, here is one pitfall, but i see someone who did that also doesn't know c++ very well. Ok i lost patience... sorry.
Prolem is still, i tried dynamic_cast and no chance, it doesn't work so probably You don't have virtual function, so either You have to modify inheritance (if there wouldn't be multiple inheritance, then there would be no problem).


Ceniza:
I just checked the value of this on both ToolsManager::Execute and ToolsManager::OnTerminate and it's the same, just as it should be.

The cast in there, for what it's used, makes no harm at all. The whole idea of it is that when the PipedProcess is notified about tool termination the pointer ToolsManager::m_pProcess is modified from PipedProcess to indicate just that. Since sizeof(void **) == sizeof(PipedProcess **) and there's no need to adjust offsets (what you might be wondering about that cast), it'll work. In fact that would also work for any kind of pointee (including built-in types), not just PipedProcess.

Now, the purpose of m_pProcess is to know if there's a tool running, just that. If you try to run another tool and m_pProcess is not 0, you'll get a message saying there's another tool already running. It's just being sure the "process terminated setting that pointer to 0" trick is applied as soon as the tool finishes. It'll also create a new event which will get ToolsManager::OnTerminate executed, which BTW sets the pointer once again to 0. This suggests the cast could be replaced by a plain 0 (a NULL pointer) and it should work.

If you check what's that pointer being used for in PipedProcess, you'll find it's just used to set to 0 the pointer it's pointing to. It'sn't casted to anything else and then trying to call a member function of the resulting pointer.

That said, keeping it that way, it'll do what it's intended to do.

If you really dislike that C-cast (I do), it could, at most, be replaced by a reinterpret_cast, even though unnecessary.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version