reentrant functions

Denys Vlasenko vda.linux at googlemail.com
Sun Jun 8 13:50:45 UTC 2008


On Sunday 08 June 2008 14:18, Bernd Schmidt wrote:
> One of the gains from dropping the non-reentrant ones comes from 
> eliminating static arrays.  In current uClibc, these static arrays are 
> eliminated by the use of uc_malloc, which has the drawback that all of 
> these functions can suddenly call exit, contrary to their documentation. 
>
> I'd like to get that reverted.

When this "why?" question was asked for the first time, I replied
with the explanation why I think using __uc_malloc is no worse
than using static arrays.

There was no response. Or maybe I missed a response somehow.

I am interested in hearing where my logic is flawed.
My reasoning is in this message:

----------  Forwarded Message  ----------

Subject: Re: __uc_malloc
Date: Tuesday 12 February 2008 16:45
From: Denys Vlasenko <vda.linux at googlemail.com>
To: Bernd Schmidt <bernds_cb1 at t-online.de>
Cc: uClibc <uclibc at uclibc.org>

On Tuesday 12 February 2008 15:18, Bernd Schmidt wrote:
> Denys Vlasenko wrote:
> >> Before I apply this, I wanted to start a discussion about whether
> >> __uc_malloc is a good idea at all.  Space savings are all well and good,
> >> but these come at a cost in reliability.
> > 
> > There is no cost in reliability.
> > 
> > Face it: if you have no free memory - you have no free memory.
> > Just allocating a big static object (like des.c was doing)
> > cannot magically guarantee that you will have this memory.
> > It just shifts failure to some other place - program might fail to load,
> > or hit malloc failure earlier in other plase, because des.c ate 70k.
> 
> IMO it's much better to have it fail with out of memory in places where
> such behaviour is expected and documented as a possibility.

Ok, this is a scenario: the user runs a "passwd" utility on NOMMU box.
This utility has 20k of text and 80k of data. 70k of this data
is occupied by des.c static buffer.

At this moment the machine has only 90k RAM available, has no swap etc.
It cannot satisfy load request for this application.
So user gets some error message from the shell to this effect.

If des.c buffer is not static but is __uc_malloc'ed, program will
load succesfully, and then __uc_malloc will fail and exit
with "no memory!" message.

In both cases user's experience is essentially the same - [s]he cannot
run the program because there is not enough memory.

> >> A number of libc functions can 
> >> now call exit, even though this is not documented and not expected by
> >> any programs that call them.

Similarly, say, a number of fucnctions can touch static arrays
in bss. On MMU system, memory pages will be supplied on demand, on first
access. What will happen if system has exactly ZERO free pages
and no pages are freeable? On Linux, this will trigger OOM killer.
So, shall we outlaw static arrays in bss too?

> > This is not exactly true. They can exit *if* program author did not
> > install alternative handler for __uc_malloc failure.
> 
> And __uc_malloc is documented in which standard? 

None.

> Which manpage tells 
> program authors about the function calls that may need a handler installed?

Author doesn't need to care which functions can trigger this.
It's similar to the fact that you don't need to decide
which libc function can overflow the stack on NOMMU CPU -
any function can, if stack is already tight enough
when you call it.

Author only needs to decide _what to do_ if __uc_malloc_ fails,
in case default behaviour of doing "_exit(1)"
is not desirable.

Example:

#ifdef __UCLIBC__
static void uc_malloc_failed()
{
    write(2, "out of memory\n", sizeof("out of memory\n") - 1);
    _exit(1);
}
#endif

int main()
{
#ifdef __UCLIBC__
    __uc_malloc_failed = uc_malloc_failed;
#endif
    ...
}

--
vda
-------------------------------------------------------



More information about the uClibc mailing list