From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 56650 invoked by alias); 19 May 2019 19:37:35 -0000 Mailing-List: contact libc-help-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: libc-help-owner@sourceware.org Received: (qmail 56640 invoked by uid 89); 19 May 2019 19:37:35 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=0.2 required=5.0 tests=AWL,BAYES_00,HTML_MESSAGE,SPF_PASS autolearn=ham version=3.3.1 spammy=topic, H*c:alternative, business, states X-HELO: muller.mulle-kybernetik.com Received: from muller.mulle-kybernetik.com (HELO muller.mulle-kybernetik.com) (78.46.34.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 19 May 2019 19:37:32 +0000 Received: (qmail 98823 invoked from network); 19 May 2019 21:37:30 +0200 Received: from unknown (HELO ?192.168.2.34?) (nat@78.46.34.175) by mail.mulle-kybernetik.com with ESMTPS (ECDHE-RSA-AES128-SHA encrypted); 19 May 2019 21:37:30 +0200 Subject: Re: Problem with atexit and _dl_fini To: Florian Weimer Cc: libc-help@sourceware.org References: <87blzypg5j.fsf@mid.deneb.enyo.de> From: Nat! Message-ID: <0a7c2435-43f8-8dfb-83ab-22ceff7ca51c@mulle-kybernetik.com> Date: Sun, 19 May 2019 19:37:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <87blzypg5j.fsf@mid.deneb.enyo.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-SW-Source: 2019-05/txt/msg00028.txt.bz2 On 19.05.19 18:23, Florian Weimer wrote: > * Nat!: > >> So my problem is, that I observe that my atexit calls are not executed >> in the correct order. >> >> i.e. atexit( a); atexit( b);  should result in b(), a() being called in >> that order. To quote the man page, >> >> "the registered functions are invoked in reverse order". >> >> >> When I register with `atexit` I can see my functions being added >> properly within `__internal_atexit` in the >> >> correct order. Finally after my functions, the elf-loader ? also adds >> itself there. So it is being called first by >> >> `__run_exit_handlers`. >> >> >> Then comes the part where it goes wrong. I registered my two function >> with `__internal_atexit`, but for some reason >> >> `_dl_fini` is calling `__cxa_finalize` and that is calling the wrong >> function first. > When atexit is called from a DSO, glibc calls the registered function > before the DSO is unloaded. This choice was made because after > unloading, the function pointer becomes invalid. > > I haven't checked, but I suspect atexit still works this way even if > it doesn't have to (because the DSO is never unloaded). > I understand, but the behavior is wrong :) The C standard (or the C++ standard for this matter) http://www.cplusplus.com/reference/cstdlib/atexit/ states that ``` If more than one atexit function has been specified by different calls to this function, they are all executed in reverse order as a stack (i.e. the last function specified is the first to be executed at exit). ``` I think its been shown that glibc can violate this C standard, so for me the argument would be over here already. That one should unwind in the reverse order is, I assume, not a interesting discussion topic. Currently atexit as a reliable mechanism is broken. But I also don't think the way this is currently handled in glibc, can't be of much use to anyone. Case 1: a regular exe linked with shared libraries, nothing gets unloaded at exit, so what's the point ? Case 2: someone manually unloads a shared library, that contains atexit code. The bug is either using `atexit` for a shared library that gets unloaded, or unloading a shared library that contains atexit code. But it's not really glibcs business IMO. Case 3: some automatism unloads shared libraries. Then the automatism should check if atexit code is affected and not unload, because the shared library is still clearly needed. It's a bug in the automatism. If one was hellbent on trying to support atexit for unloading shared libraries, an atexit contained in a shared library should up the reference count of the shared library during the atexit call and decrement after the callback has executed. Ciao    Nat!