From: Juho Snellman Date: Tue, 27 Sep 2005 16:58:47 +0000 (+0000) Subject: 0.9.5.2: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=b319107330cea71911b346974508c699f8b7fe6c;p=sbcl.git 0.9.5.2: Yet another personality() change, this time for some Linux kernels that don't change the personality, but nor return an error code. Patch by Svein Ove Aas on sbcl-devel, "[PATCH] Workaround buggy personality() call on old Linux kernels". Reformat isnptl(). --- diff --git a/NEWS b/NEWS index 4f2cf44..924cc35 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,9 @@ ;;;; -*- coding: utf-8; -*- +changes in sbcl-0.9.6 relative to sbcl-0.9.5: + * bug fix: add a workaround to SBCL looping infinitely at startup on + Linux kernels with apparently buggy implementations of personality(). + (thanks to Svein Ove Aas) + changes in sbcl-0.9.5 relative to sbcl-0.9.4: * new feature: timers based on Zach Beane's excellent timer package * added support for the following external formats: koi8-u, diff --git a/src/runtime/linux-os.c b/src/runtime/linux-os.c index 9bc5ea1..4cbd8c9 100644 --- a/src/runtime/linux-os.c +++ b/src/runtime/linux-os.c @@ -98,16 +98,17 @@ int linux_sparc_siginfo_bug = 0; int linux_no_threads_p = 0; #ifdef LISP_FEATURE_SB_THREAD -int isnptl (void) +int +isnptl (void) { size_t n = confstr (_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); - if (n > 0) - { + if (n > 0) { char *buf = alloca (n); confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, n); - if (strstr (buf, "NPTL")) - return 1; - } + if (strstr (buf, "NPTL")) { + return 1; + } + } return 0; } #endif @@ -163,10 +164,21 @@ Please use a more recent kernel or a version of SBCL without threading support.\ if ((major_version == 2 && minor_version >= 6) || major_version >= 3) { - long pers = personality(-1); + int pers = personality(0xffffffffUL); /* 0x40000 aka. ADDR_NO_RANDOMIZE */ if (!(pers & 0x40000)) { - if (personality(pers | 0x40000) != -1) { + int retval = personality(pers | 0x40000); + /* Allegedly some Linux kernels (the reported case was + * "hardened Linux 2.6.7") won't set the new personality, + * but nor will they return -1 for an error. So as a + * workaround query the new personality... + */ + int newpers = personality(0xffffffffUL); + /* ... and don't re-execute if either the setting resulted + * in an error or if the value didn't change. Otherwise + * this might result in an infinite loop. + */ + if (retval != -1 && newpers != pers) { /* Use /proc/self/exe instead of trying to figure out * the executable path from PATH and argv[0], since * that's unreliable. We follow the symlink instead of diff --git a/version.lisp-expr b/version.lisp-expr index 1fee710..eb3ba00 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.9.5.1" +"0.9.5.2"