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

crash on close cbp project (rev 7773)

(1/6) > >>

ollydbg:
gdb points to here:

--- Code: ---bool cbProject::CloseAllFiles(bool dontsave)
{
    // first try to close modified editors

    if (!dontsave && !QueryCloseAllFiles())
            return false;

    // now free the rest of the project files
    Manager::Get()->GetEditorManager()->HideNotebook();
    FilesList::iterator it = m_Files.begin();
    while (it != m_Files.end())
    {
        ProjectFile* f = *it;
        if (f)
        {
            Manager::Get()->GetEditorManager()->Close(f->file.GetFullPath(),true);
        }
        m_Files.erase(it);
        m_FileArray.Remove(*it); //crash here****************************
        delete f;
        it = m_Files.begin();
    }
    Manager::Get()->GetEditorManager()->ShowNotebook();

    return true;
}

--- End code ---

No time to find the reason right now.

ollydbg:
I test this again, but it does not crash every time I close the cbp project.

But I found another crash after I close the C::B, gdb point to the desturctor of ClassBrowser.
1, start c::b.
2, close c::b, and it crashes.

--- Code: ---// class destructor
ClassBrowser::~ClassBrowser()
{
    int pos = XRCCTRL(*this, "splitterWin", wxSplitterWindow)->GetSashPosition();
    Manager::Get()->GetConfigManager(_T("code_completion"))->Write(_T("/splitter_pos"), pos);

    SetParser(NULL);

    if (m_ClassBrowserBuilderThread)
    {
        m_ClassBrowserSemaphore.Post();
        // m_ClassBrowserBuilderThread->Delete(); --> would delete it twice and leads to a warning
        m_ClassBrowserBuilderThread->Wait();
    }
}

--- End code ---

oBFusCATed:
http://forums.codeblocks.org/index.php/topic,15882.0.html


--- Quote from: ollydbg on February 05, 2012, 02:45:39 am ---gdb points to here:

--- Code: ---        m_Files.erase(it);
        m_FileArray.Remove(*it); //crash here****************************
        delete f;

--- End code ---

--- End quote ---

The iterator is invalid, after the erase method. The correct code is m_FileArray.Remove(f); I guess. Or you can swap the two methods (erase and Remove):)

Jenna:

--- Quote from: oBFusCATed on February 05, 2012, 10:34:58 am ---The iterator is invalid, after the erase method. The correct code is m_FileArray.Remove(f); I guess. Or you can swap the two methods (erase and Remove):)

--- End quote ---

Definitely not, because:

--- Code: ---ProjectFile* f = *it;
--- End code ---

The fix by Pecan and committed by Thomas is also not a fix in my opinion (or wxWidgets has a bug in the Remove-function), but it does no harm.

I'm not sure if an invalid iterator is really the cause for it (I did not dig into the sources of wxWidgets deeper, to see whether the iterator can be invalid in this case).

Just changeing the order of removal should do it, first

--- Code: ---        m_FileArray.Remove(*it);
--- End code ---
and then

--- Code: ---        m_Files.erase(it);
--- End code ---

In this case the iterator can not be invalid.

In most cases the Remove-method is called on an empty Array, because the array only gets filled if cbProject::GetFile was called at least once, and this is only done by script-functions at the moment.
According to the wxWidgets documentation we can get an assert in debug-mode, but in release-mode just nothing happens, if the element we try to remove does not exist.
If the cause for the crash should be, that we try to remove a not-existing element, we would need to check whether the array is empty and in this case not run the Remove-method.

Jenna:
I hope it's finally fixed with svn r7777 (with this revision-number it must be fixed  ;) ).

Additionally closing large projects should be much faster.
My very large test-project (linux kernel 2.6.35 with more than 30000 files) closes about 4 times faster (1200 ms instead of almost 5000 ms).
Times are measured without codecompletion-plugin, which is a little bit unstable at the moment.

Navigation

[0] Message Index

[#] Next page

Go to full version