Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 22 Jul 2015 21:18:16 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: [PATCH] fix atexit when it is called from an atexit
 handler

On Thu, Jul 23, 2015 at 01:44:06AM +0200, Szabolcs Nagy wrote:
> When running atexit handlers always restart iterating the list of
> handlers so if new ones are registered they are called in the right
> order.
> 
> Note that the iteration changes the head pointer in an irreversible
> way, this is not a problem, but may cause more allocations than
> optimal when new handlers are registered during exit.
> 
> The old code accepted atexit handlers after exit, but did not run
> them.  C11 seems to explicitly allow atexit to fail in this case,
> but this situation can easily come up in C++ if a destructor has
> local static object with a destructor so it should be handled.
> ---
>  src/exit/atexit.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/src/exit/atexit.c b/src/exit/atexit.c
> index be82718..a0fd8d7 100644
> --- a/src/exit/atexit.c
> +++ b/src/exit/atexit.c
> @@ -14,13 +14,24 @@ static struct fl
>  
>  static volatile int lock[2];
>  
> +static int next()
> +{
> +	int i;
> +	for (; head; head=head->next)
> +		for (i=COUNT-1; i>=0; i--)
> +			if (head->f[i])
> +				return i;
> +	return -1;
> +}
> +
>  void __funcs_on_exit()
>  {
>  	int i;
>  	void (*func)(void *), *arg;
>  	LOCK(lock);
> -	for (; head; head=head->next) for (i=COUNT-1; i>=0; i--) {
> -		if (!head->f[i]) continue;
> +	for (;;) {
> +		i = next();
> +		if (i<0) break;
>  		func = head->f[i];
>  		arg = head->a[i];
>  		head->f[i] = 0;

I agree that this change should be made, but I don't like the
particulars of the patch. It seems to increase exit handler runtime to
O(n²) even in the case where no atexit is happening during exit, and
it's not very elegant. I think a simpler solution would be to reset i
to COUNT after calling f[i] if either (1) head has changed, or (2)
i<COUNT-1 and f[i+1] is nonzero. Does this sound correct/better?

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.