Author Topic: Compiler plugin bug  (Read 8292 times)

Offline comsytec

  • Multiple posting newcomer
  • *
  • Posts: 58
    • www.comsytec.com
Compiler plugin bug
« on: November 22, 2013, 10:04:26 pm »
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
        }

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
        }

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.

Offline osdt

  • Multiple posting newcomer
  • *
  • Posts: 63
Re: Compiler plugin bug
« Reply #1 on: November 23, 2013, 02:20:02 am »
Discovered following compiler bug:

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

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
« Last Edit: November 23, 2013, 05:19:39 am by osdt »

Offline comsytec

  • Multiple posting newcomer
  • *
  • Posts: 58
    • www.comsytec.com
Re: Compiler plugin bug
« Reply #2 on: November 23, 2013, 10:34:51 am »
Code
CompilerGCC::BuildJobTarget& CompilerGCC::PeekNextJob()
{
    static BuildJobTarget ret;
    ret = BuildJobTarget();

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

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.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Compiler plugin bug
« Reply #3 on: November 24, 2013, 09:19:13 pm »
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
         {
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline comsytec

  • Multiple posting newcomer
  • *
  • Posts: 58
    • www.comsytec.com
Re: Compiler plugin bug
« Reply #4 on: November 25, 2013, 10:44:23 am »
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.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Compiler plugin bug
« Reply #5 on: November 25, 2013, 11:04:54 pm »
In svn...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline comsytec

  • Multiple posting newcomer
  • *
  • Posts: 58
    • www.comsytec.com
Re: Compiler plugin bug
« Reply #6 on: November 27, 2013, 05:09:22 pm »
Will be released this year ?

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Compiler plugin bug
« Reply #7 on: November 27, 2013, 05:45:25 pm »
Will be released this year ?
If you watch the SVN log carefully you'll know... ;-)
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ