From owner-freebsd-current@FreeBSD.ORG Tue Aug 14 18:10:46 2007 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D0F1016A520 for ; Tue, 14 Aug 2007 18:10:46 +0000 (UTC) (envelope-from mi@bonkers.video-collage.com) Received: from bonkers.video-collage.com (static-151-204-231-237.bos.east.verizon.net [151.204.231.237]) by mx1.freebsd.org (Postfix) with ESMTP id B885413C478 for ; Tue, 14 Aug 2007 18:10:45 +0000 (UTC) (envelope-from mi@bonkers.video-collage.com) Received: from bonkers.video-collage.com (localhost [127.0.0.1]) by bonkers.video-collage.com (8.14.1/8.14.1) with ESMTP id l7EHVH21025564 for ; Tue, 14 Aug 2007 13:31:17 -0400 (EDT) (envelope-from mi@bonkers.video-collage.com) Received: (from mi@localhost) by bonkers.video-collage.com (8.14.1/8.14.1/Submit) id l7EHVGI0025563 for current@freebsd.org; Tue, 14 Aug 2007 13:31:16 -0400 (EDT) (envelope-from mi) From: Mikhail Teterin To: current@freebsd.org Date: Tue, 14 Aug 2007 13:06:04 -0400 User-Agent: KMail/1.7.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200708141306.05102.mteterin@meowmeow> X-KMail-EncryptionState: X-KMail-SignatureState: X-KMail-MDN-Sent: X-UID: 1087717 X-Keywords: Sender: mi@bonkers.video-collage.com X-Virus-Scanned: ClamAV 0.88.7/3957/Tue Aug 14 01:48:58 2007 on bonkers.video-collage.com X-Virus-Status: Clean X-Mailman-Approved-At: Tue, 14 Aug 2007 19:15:14 +0000 Cc: Subject: atexit vs. dlclose X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Aug 2007 18:10:46 -0000 Hello! The current implementation of atexit and dlclose allow programs to be shot in the tail by dlclose-ing a shared library, which may contain an atexit-scheduled function. In this case the program will seg-fault upon otherwise clean exit. Although usually benign, this may prevent other atexit-registered functions from ever being called -- potentially causing far more disruption than a random core-dump file here and there. Our current attitude is "atexit should not be called from shared libraries. Ha-ha." Although this is, likely, true, we could do better -- the atexit-scheduled function can be looked up in the list of the dlopen-ed libraries (by scanning the linked list and checking, whether the passed pointer is between mapbase and mapbase+textsize of any of the Obj_Entries). Here are the approaches I can think of: 1. atexit to bump up the shared object's ref-count. A re-implementation of atexit() (under libexec/rtld-elf someplace) will scan through the dlopen-ed objects. If the atexit's argument is found to belong to an object, that object's dl_refcount will be increased. This will cause the object to survive the explicit dlclose(), although it may still not survive, if the application calls dlclose an extra time. 2. dlclose to refuse unloading the object This way it will be the dlclose, that will perform the check -- for each symbol registered through atexit, it will check, whether the shared object being closed owns the symbol and fail with a descriptive error dlerror (and warnx?), if it does. I personally favour the second approach more, because it provides for more descriptive diagnostics and requires less invasive implementation (no atexit re-implementation). It will also survive multiple calls to dlclose, thus being more helpful to erroneous programmers. I can see, however, how the first approach can be argued to be "more elegant", though... What do you think? -mi