public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jeff Law <law@redhat.com>
To: Aldy Hernandez <aldyh@redhat.com>,
	       Richard Biener <richard.guenther@gmail.com>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: protected alloca class for malloc fallback
Date: Thu, 04 Aug 2016 19:24:00 -0000	[thread overview]
Message-ID: <87147ff6-0133-0ba7-17ae-980fe425bf57@redhat.com> (raw)
In-Reply-To: <57A35CF6.1040504@redhat.com>

On 08/04/2016 09:19 AM, Aldy Hernandez wrote:

>>>
>>> Particularly irritating and error prone is having to free malloc'd
>>> pointers
>>> on every function exit point.  We end up with a lot of:
>>>
>>> foo(size_t len)
>>> {
>>>    void *p, *m_p = NULL;
>>>    if (len < HUGE)
>>>      p = alloca(len);
>>>    else
>>>      p = m_p = malloc(len);
>>>    if (something)
>>>      goto out;
>>>    stuff();
>>> out:
>>>    free (m_p);
>>> }
>>>
>>> ...which nobody really likes.
Yup.  You'll see that all over glibc.  I don't think we use that idiom 
all that much for GCC.

>>>
>>> I've been thinking that for GCC we could have a protected_alloca
>>> class whose
>>> destructor frees any malloc'd memory:
>>>
>>> void foo()
>>> {
>>>    char *p;
>>>    protected_alloca chunk(50000);
>>>    p = (char *) chunk.pointer();
>>>    f(p);
>>> }
>>>
>>> This would generate:
>>>
>>> void foo() ()
>>> {
>>>    void * _3;
>>>
>>>    <bb 2>:
>>>    _3 = malloc (50000);
>>>    f (_3);
>>>
>>>    <bb 3>:
>>>    free (_3); [tail call]
>>>    return;
>>> }
>>>
>>> Now the problem with this is that the memory allocated by chunk is freed
>>> when it goes out of scope, which may not be what you want.  For example:
>>>
>>>       func()
>>>       {
>>>         char *str;
>>>         {
>>>           protected_alloca chunk (99999999);
>>>           // malloc'd pointer will be freed when chunk goes out of
>>> scope.
>>>           str = (char *) chunk.pointer ();
>>>         }
>>>         use (str);  // BAD!  Use after free.
>>>       }
>>
>> But how's that an issue if the chunk is created at the exact place
>> where there
>> previously was an alloca?
>
> The pointer can escape if you assign it to a variable outside the scope
> of chunk?  Take for instance the following snippet in tree.c:
Right.  The alloca model is (with the exception of vlas in loops) is the 
storage hangs around until function scope is left.  So releasing on exit 
of the scope in which the space was allocated is wrong unless allocation 
occurred at function scope.

That doesn't play as well with an RAII model where objects get destroyed 
as soon as they leave their lexical scope.



So
>
>     {
>     ...
>     ...
>       q = (char *) alloca (9 + 17 + len + 1);
>       memcpy (q, file, len + 1);
>
>       snprintf (q + len, 9 + 17 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX,
>         crc32_string (0, name), get_random_seed (false));
>
>       p = q;
>     }
>
>     clean_symbol_name (q);
>
> If you define `protected_alloca chunk(9 + 17 + len + 1)' at the alloca()
> call, chunk will be destroyed at the "}", whereas `q' is still being
> used outside of that scope.
>
> What I am suggesting for this escaping case is to define
> "protected_alloca chunk()" at function scope, and then do chunk.alloc(N)
> in the spot where the alloca() call was previously at.
>
> Or am I missing something?
I think only thing you're missing is that we probably don't want to be 
using alloca in new code anyway.  And if we're going through the trouble 
of fixing old code, we ought to just remove alloca.  So building up this 
kind of class is probably taking folks in the wrong direction.

Now you might use that opportunity to convert some object to a RAII 
model (and I'm a huge fan of that model).

Jeff

  reply	other threads:[~2016-08-04 19:24 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-04 11:30 Aldy Hernandez
2016-08-04 12:58 ` Richard Biener
2016-08-04 15:19   ` Aldy Hernandez
2016-08-04 19:24     ` Jeff Law [this message]
2016-08-05 14:37       ` Aldy Hernandez
2016-08-05 15:15         ` Pedro Alves
2016-08-05 16:23         ` Jeff Law
2016-08-05 17:48           ` Richard Biener
2016-08-05  8:17     ` Richard Biener
2016-08-04 19:06 ` Pedro Alves
2016-08-04 19:16   ` Jeff Law
2016-08-04 19:22     ` Pedro Alves
2016-08-04 19:26       ` Jeff Law
2016-08-04 19:31         ` Pedro Alves
2016-08-05  2:10 ` Martin Sebor
2016-08-05 14:42   ` Aldy Hernandez
2016-08-05 17:56     ` Richard Biener
2016-08-05 18:16       ` Oleg Endo
2016-08-05 20:07         ` Richard Biener
2016-08-06 10:09           ` Aldy Hernandez
2016-08-06 10:15           ` Aldy Hernandez
2016-08-06 15:08             ` Richard Biener
2016-08-08 17:00               ` Jeff Law
2016-08-08 17:32                 ` Trevor Saunders
2016-08-08 19:03                   ` Richard Biener
2016-08-09 11:34                   ` Oleg Endo
2016-08-09 17:34                     ` Trevor Saunders
2016-08-10 17:03                       ` Oleg Endo
2016-08-11  1:23                         ` Trevor Saunders
2016-08-11 12:18                           ` Oleg Endo
2016-08-11 17:55                             ` Trevor Saunders
2016-08-20  2:29                         ` Mike Stump
2016-08-21 20:00                           ` C++11? (Re: protected alloca class for malloc fallback) Pedro Alves
2016-08-22  7:10                             ` Trevor Saunders
2016-08-22  7:28                               ` Richard Biener
2016-08-22 12:02                             ` Eric Gallager
2016-08-22 12:58                               ` Manuel López-Ibáñez
2016-08-22 22:08                               ` Mike Stump
2016-08-23 23:17                                 ` Eric Gallager
2016-08-09 13:17       ` protected alloca class for malloc fallback Aldy Hernandez
2016-08-09 13:21         ` Bernd Schmidt
2016-08-10 10:04         ` Richard Biener
2016-08-10 10:12           ` Aldy Hernandez
2016-08-10 10:39             ` Richard Biener
2016-08-10 18:00           ` Jeff Law
2016-08-10 18:33             ` Richard Biener
2016-08-16 16:28               ` Jeff Law
2016-08-16 16:44                 ` Jakub Jelinek
2016-08-16 16:47                   ` Jeff Law
2016-08-16 17:54                     ` Martin Sebor
2016-08-17  8:27                       ` Richard Biener
2016-08-17 13:39                         ` Martin Sebor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87147ff6-0133-0ba7-17ae-980fe425bf57@redhat.com \
    --to=law@redhat.com \
    --cc=aldyh@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).