Stories
Slash Boxes
Comments

SoylentNews is people

posted by martyb on Tuesday May 02 2017, @10:08AM   Printer-friendly
from the bug++ dept.

Submitted via IRC for TheMightyBuzzard to let us know that a serious bug in GCC.

This post is to inform you about a bug in GCC that may cause memory (or other resource) leaks in your valid C++ programs.

One of the pillars of C++ philosophy is what we often call RAII [Resource Acquisition Is Initialization]: if you use classes to manage resources, use constructors for allocating resources and destructors for releasing them, the language makes sure that whatever happens, however you use such classes the resources will get properly released.

[...] This is the contract: I take care that my classes correctly manage resources, and the language takes care that the resources will always be managed correctly regardless of the complexity of the program.

This is where the bug manifests. Member r1 is initialized but never destroyed. Admittedly, this is a rare case: it requires an exception in the middle of initialization, a temporary and an aggregate initialization. But usually, leaks manifest in the face of exceptions. And the fact that it is rare makes you less prepared for it.

Here is a full example:

#include <cstdio>
#include <stdexcept>

struct Resource
{
  explicit Resource(int) { std::puts("create"); }
  Resource(Resource const&) { std::puts("create"); }
  ~Resource() { std::puts("destroy"); }
};

Resource make_1() { return Resource(1); }
Resource make_2() { throw std::runtime_error("failed"); }

struct User
{
  Resource r1;
  Resource r2;
};

void process (User) {}

int main()
{
  try {
    process({make_1(), make_2()});
  }
  catch (...) {}
}

You can test it online here. It is present in GCC 4, 5, and 6. For a more real-life, and somewhat longer, illustration of the problem, see this example provided by Tomasz Kamiński.

Interesting but thankfully not my worry at the moment as I'm on a Learn Rust kick and my problem areas of SN are all perl.

Source: https://akrzemi1.wordpress.com/2017/04/27/a-serious-bug-in-gcc/


Original Submission

 
This discussion has been archived. No new comments can be posted.
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • (Score: 4, Informative) by Wootery on Tuesday May 02 2017, @10:26AM (5 children)

    by Wootery (2341) on Tuesday May 02 2017, @10:26AM (#502742)

    Not a compiler bug, but make_shared exists for a related issue: exceptions can cause memory leaks if you allocate in-place with an argument.

    This is explained well on StackOverflow [stackoverflow.com]. If an allocation is made during evaluation of one of your arguments, and an exception is then thrown during the evaluation of one of your other arguments, you can end up leaking memory. The problem is avoided by using make_shared which uses smart-pointers in such a way that you get safe clean-up even for a convoluted allocate+throw case.

    See also. [cppreference.com]

    (The other reason make_shared exists is to combine two allocations into one for non-intrusive smart-pointers, but that issue is much less fun.)

    Starting Score:    1  point
    Moderation   +2  
       Informative=2, Total=2
    Extra 'Informative' Modifier   0  
    Karma-Bonus Modifier   +1  

    Total Score:   4  
  • (Score: 2) by andersjm on Tuesday May 02 2017, @03:43PM (4 children)

    by andersjm (3931) on Tuesday May 02 2017, @03:43PM (#502899)

    It's not the same thing. What you're missing is that there's no new anywhere in this code. The object returned by make_1 has automatic (stack) storage duration, and as such it's the implementation's responsibility to make sure it's cleaned up.

    • (Score: 2) by Wootery on Tuesday May 02 2017, @04:07PM (3 children)

      by Wootery (2341) on Tuesday May 02 2017, @04:07PM (#502918)

      Was I not clear enough that I'm already aware it's not exactly the same thing?

      • (Score: 0) by Anonymous Coward on Tuesday May 02 2017, @06:31PM

        by Anonymous Coward on Tuesday May 02 2017, @06:31PM (#503017)

        ☑ Did not RTFA
        ☑ Did not RTFS
        ☑ Did not even read the comment they replied to!

        ACHIEVEMENT UNLOCKED!!!

      • (Score: 2) by andersjm on Tuesday May 02 2017, @07:53PM (1 child)

        by andersjm (3931) on Tuesday May 02 2017, @07:53PM (#503097)

        Sorry, I misunderstood: I read the words "Not a compiler bug" and thought you were referring to the article.

        • (Score: 2) by Wootery on Wednesday May 03 2017, @08:13AM

          by Wootery (2341) on Wednesday May 03 2017, @08:13AM (#503522)

          Gotcha -- yes, that was a clunky bit of writing on my part.