Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development

Compiler plugin bug

(1/2) > >>

comsytec:
Discovered following compiler bug:


--- Code: ---        case bsTargetDone:
        {
            // get next build job
            if (m_BuildJob != bjTarget)
            {
                BuildJobTarget& bj = PeekNextJob();                          // <--------------- reference
                if (bj.project && bj.project == m_pBuildingProject)
                {
                    // same project, switch target
                    bj = GetNextJob(); // remove job from queue         // <-------- refers to deleted memory
                    m_BuildingTargetName = bj.targetName;
                    // switching targets
                    if (clean && !build)
                        return bsTargetClean;

                    return bsTargetPreBuild;
                }
                // switch project
                // don't run postbuild step, if we only clean the project
                if (build)
                    return bsProjectPostBuild;

                return bsProjectDone;
            }
            m_pBuildingProject->SetCurrentlyCompilingTarget(0);
            break; // all done
        }

--- End code ---

should be


--- Code: ---        case bsTargetDone:
        {
            // get next build job
            if (m_BuildJob != bjTarget)
            {
                BuildJobTarget bj = PeekNextJob();                               <---------- fix
                if (bj.project && bj.project == m_pBuildingProject)
                {
                    // same project, switch target
                    GetNextJob(); // remove job from queue                   <---------- fix
                    m_BuildingTargetName = bj.targetName;
                    // switching targets
                    if (clean && !build)
                        return bsTargetClean;

                    return bsTargetPreBuild;
                }
                // switch project
                // don't run postbuild step, if we only clean the project
                if (build)
                    return bsProjectPostBuild;

                return bsProjectDone;
            }
            m_pBuildingProject->SetCurrentlyCompilingTarget(0);
            break; // all done
        }

--- End code ---

Perhaps I found actual first snippet for proper trunk. This was discovered by bulk project compiling using script console. Always crashed after 21 projects compiled.

osdt:

--- Quote from: comsytec on November 22, 2013, 10:04:26 pm ---Discovered following compiler bug:


--- Code: ---                    bj = GetNextJob(); // remove job from queue         // <-------- refers to deleted memory

--- End code ---

--- End quote ---

Hm, it's not a reference to deleted memory. CompilerGCC::GetNextJob() returns a temporary instance (not a reference) and bj will point to this temporary.

EDIT: don't know about the temporary's scope. If it's destructed right after the assignment, it's a bug.

- osdt

comsytec:

--- Code: ---CompilerGCC::BuildJobTarget& CompilerGCC::PeekNextJob()
{
    static BuildJobTarget ret;
    ret = BuildJobTarget();

    if (m_BuildJobTargetsList.empty())
        return ret;
    return m_BuildJobTargetsList.front();
}

--- End code ---

but the instance returned is

m_BuildJobTargetsList.front();

and it is assigned to reference. So I think it refers to same place a not to temporary place. I dont know how the front() is solved internally.

oBFusCATed:
comsytec:
Can you try this patch and tell me if it fixes the problem for you?
Also can you provide a simple workspace that can be used to reproduce the problem?


--- Code: ---Index: src/plugins/compilergcc/compilergcc.cpp
===================================================================
--- src/plugins/compilergcc/compilergcc.cpp     (revision )
+++ src/plugins/compilergcc/compilergcc.cpp     (working copy)
@@ -2175,12 +2175,12 @@ BuildState CompilerGCC::GetNextStateBasedOnJob()
             // get next build job
             if (m_BuildJob != bjTarget)
             {
-                BuildJobTarget& bj = PeekNextJob();
+                const BuildJobTarget& bj = PeekNextJob();
                 if (bj.project && bj.project == m_pBuildingProject)
                 {
                     // same project, switch target
-                    bj = GetNextJob(); // remove job from queue
                     m_BuildingTargetName = bj.targetName;
+                    GetNextJob(); // remove job from queue, bj points to a destructed object
                     // switching targets
                     if (clean && !build)
                         return bsTargetClean;
@@ -2540,10 +2540,9 @@ CompilerGCC::BuildJobTarget CompilerGCC::GetNextJob()
     return ret;
 }

-CompilerGCC::BuildJobTarget& CompilerGCC::PeekNextJob()
+const CompilerGCC::BuildJobTarget& CompilerGCC::PeekNextJob()
 {
     static BuildJobTarget ret;
-    ret = BuildJobTarget();

     if (m_BuildJobTargetsList.empty())
         return ret;
Index: src/plugins/compilergcc/compilergcc.h
===================================================================
--- src/plugins/compilergcc/compilergcc.h       (revision )
+++ src/plugins/compilergcc/compilergcc.h       (working copy)
@@ -252,7 +252,7 @@ class CompilerGCC : public cbCompilerPlugin
         void ExpandTargets(cbProject* project, const wxString& targetName, wxArrayString& result);
         void PreprocessJob(cbProject* project, const wxString& targetName);
         BuildJobTarget GetNextJob();
-        BuildJobTarget& PeekNextJob();
+        const BuildJobTarget& PeekNextJob();

         struct CompilerProcess
         {

--- End code ---

comsytec:
Your solution looks very similar to my 1st post fixes (tested and working). It seems to be correct (difference only in some const decls). With simple workspace I cannot seen this bug. This bug appears when we are running a squirrel script from script console. Script is generating and building lot of projects automatically for testing purpose.

Navigation

[0] Message Index

[#] Next page

Go to full version