From owner-svn-src-head@FreeBSD.ORG Sat Nov 1 20:50:40 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id E5DD22DA; Sat, 1 Nov 2014 20:50:39 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C707E359; Sat, 1 Nov 2014 20:50:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sA1KodmY039969; Sat, 1 Nov 2014 20:50:39 GMT (envelope-from ngie@FreeBSD.org) Received: (from ngie@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sA1KodEq039948; Sat, 1 Nov 2014 20:50:39 GMT (envelope-from ngie@FreeBSD.org) Message-Id: <201411012050.sA1KodEq039948@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ngie set sender to ngie@FreeBSD.org using -f From: Garrett Cooper Date: Sat, 1 Nov 2014 20:50:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273946 - head/contrib/netbsd-tests/lib/libc/stdlib X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 Nov 2014 20:50:40 -0000 Author: ngie Date: Sat Nov 1 20:50:39 2014 New Revision: 273946 URL: https://svnweb.freebsd.org/changeset/base/273946 Log: Port h_atexit to FreeBSD __cxa_atexit varies between FreeBSD and NetBSD, and thus we must use pointers instead of static fields in the BSS. More extensive discussion is included in the source code In collaboration with: kib Submitted by: pho Modified: head/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c Modified: head/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c ============================================================================== --- head/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c Sat Nov 1 20:45:45 2014 (r273945) +++ head/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c Sat Nov 1 20:50:39 2014 (r273946) @@ -42,9 +42,33 @@ __RCSID("$NetBSD: h_atexit.c,v 1.1 2011/ extern int __cxa_atexit(void (*func)(void *), void *, void *); extern void __cxa_finalize(void *); +#if defined(__FreeBSD__) +/* + * On shared object unload, in __cxa_finalize, call and clear all installed + * atexit and __cxa_atexit handlers that are either installed by unloaded + * dso, or points to the functions provided by the dso. + * + * The reason of the change is to ensure that there is no lingering pointers + * to the unloaded code after the dlclose(3). It is known reason for infinite + * stream of the crash reports for many programs which use loadable modules + * and fail to properly clean on module unload. Examples are apache, php, + * perl etc. + * + * You pass the &dso_handle_1 and &dso_handle_2, which points inside the + * main binary, to the registration function. The code from r211706, + * correctly detects that they are for the main binary, and on the first + * call to __cxa_finalize(), which also pass pointer to main binary, all + * registered functions from the main binary are executed. + */ + +static void *dso_handle_1 = (void *)1; +static void *dso_handle_2 = (void *)2; +static void *dso_handle_3 = (void *)3; +#else static int dso_handle_1; static int dso_handle_2; static int dso_handle_3; +#endif static int arg_1; static int arg_2; @@ -167,6 +191,15 @@ main(int argc, char *argv[]) ASSERT(0 == atexit(normal_handler_0)); ASSERT(0 == atexit(normal_handler_1)); +#if defined(__FreeBSD__) + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3)); + + __cxa_finalize(dso_handle_1); + __cxa_finalize(dso_handle_2); +#else ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); @@ -174,5 +207,6 @@ main(int argc, char *argv[]) __cxa_finalize(&dso_handle_1); __cxa_finalize(&dso_handle_2); +#endif exit(0); }