Developer forums (C::B DEVELOPMENT STRICTLY!) > Development
Crash when opening workspace with non-existent projects
artoj:
Using Win XP x64 and revision 1889 SVN.
Opening a workspace that contains project which don't exist causes C::B to crash.
Steps to reproduce:
1. Open C::B and create new project, File -> New Project. I chose Console project named Console1. I saved it to Desktop\Console1\Console1.cbp.
2. Save the workspace, File -> Save workspace as... . I saved it to Desktop\wp.workspace.
3. Close C::B.
4. Delete the project directory, Desktop\Console1.
5. Double click the workspace file you created to open it in C::B.
6. C::B crashes.
The rpt file is attached.
[attachment deleted by admin]
killerbot:
confirmed, I am already working on it.
killerbot:
some first analysis (more to follow)
the offending line of code :
m_pTree->Expand(m_pActiveProject->GetProjectNode());
in ProjectManager::LoadWorkSpace
Why : the workspace only had 1 project, which was the active on, the loading of that project failed (see REMARK 1)), so the m_pActiveProject is still NULL -->crash
REMARK 1 : Where does the loading fail, or where does the system know there's a problem with the project
ProjectManager::LoadWorkSpace -> m_pWorkspace = new cbWorkspace(filename)
This leads us to : WorkspaceLoader::Open() which tries to open all projects mentioned in the workspace.
--- Code: --- wxFileName fname(projectFilename);
fname.MakeAbsolute(wfname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
int active = 0;
int ret = proj->QueryIntAttribute("active", &active);
switch (ret)
{
case TIXML_SUCCESS:
if (active == 1)
GetpMan()->LoadProject(fname.GetFullPath(), true); // activate it
break;
case TIXML_WRONG_TYPE:
GetpMsg()->DebugLog(_("Error %s: %s"), doc.Value(), doc.ErrorDesc());
GetpMsg()->DebugLog(_("Wrong attribute type (expected 'int')"));
break;
default:
GetpMan()->LoadProject(fname.GetFullPath(), false); // don;t activate it
break;
--- End code ---
In this case it's the TIXML_SUCCESS case with active == 1, and in the call to ProjectManager::LoadProject() it is discovered that the project can not be loaded, note the funtion will return NULL.
Since in the mentioned example, there are no other projects in the workspace, end of story and no m_pActiveProject.
Open Questions (for my further analysis) : what if there are more then 1 project in the workspace :
- a non active fails to load
- the active one fails to load, but others OK, m_pActiveProject still NULL ? if so make the next one active ??
It seems that in the example case, it is sure that there will never be an active project, --> offending line : if protect on m_pActiveProject != NULL.
Question : in such a case should we consider the workspace load to fail (since no project it contains was able to load) ?
.... to be continued
[EDIT 1] : just tested with 2 projects in workspace, with the 'active' one being failed, second one loads ok -> still no m_pActiveProject
[EDIT 2] : tested again with 2 projects in the workspace, but now the non-active going into failure, CodeBlocks error message box : Failed to create a temporary file name (error 267 : teh directory name is invalid), end result is the workspace is open with only the active project, second project : no sign of it.
Der Meister:
If I understood the code in the right way then cbProject::cbProject creates a new project if it can't load the given one. But: cbProject::m_Loaded is only set to true if cbProject::Save returns true. (Question: When does cbProject::Save return true and why does it return false in this case?)
After creating the cbProject instance (named project) for the deleted project-file ProjectManager::LoadProject checks if project->IsLoaded() returns true. This is obviously not the case because this should be the only situation (as long as the sanity-checks don't fail) in which ProjectManager::LoadProject could return 0. Then the project will obviously not activated (this would be the job of ProjectManager::LoadProject) and that way m_pActiveProject will be 0 if the active project fails to load.
The question now is: Is cbProject::Save (and all the functions that are called from there) supposed to return false in this case? I think If it returns true everything should go fine except that the active project is empty.
killerbot:
Correct analysis Der Meister. I also find that way of working a bit confusing. Probably save (did not check it yet) can have some arguments specifying construct if not existing or so ...
I have fixed the crash, will post my patch this evening (have to go play soccer now).
Example : 2 projects in workspace, active can not be loaded (since we removed it's directory or so), no crash, only second project loaded , that message box still shows up (will investigate that also this evening, since it's not so informative to thus user).
Result is : stil no 'active project', so you will need to activate manually the 'second' one and then you can compile it, etc ... (Build menu is mainly grayed out when no project is active).
More to come this evening ...
Navigation
[0] Message Index
[#] Next page
Go to full version