aboutsummaryrefslogtreecommitdiffstats
path: root/testing/sbcl/0003-Fix-foreign-tests-on-musl-libc.patch
blob: 2c4da211a041e4ad0d8f4f82973d41926c7f3838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#2020/01/30 Patch has not yet been accepted upstream
From 87b1eca2b719fb5e2d6f10352dcdb86f4d389ca9 Mon Sep 17 00:00:00 2001
From: Eric Timmons <etimmons@mit.edu>
Date: Sat, 1 Feb 2020 17:33:59 -0500
Subject: [PATCH 3/5] Teach foreign.test.sh about noop dlclose implementations

Musl libc's implementation of dlclose(3) is (intentionally) a noop (see:
https://wiki.musl-libc.org/functional-differences-from-glibc.html). When
running regression tests, test if dlclose is a noop and if so, skip all tests
that depend on objects being unmapped.
---
 src/code/foreign-load.lisp |  2 +-
 tests/foreign.test.sh      | 67 ++++++++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/src/code/foreign-load.lisp b/src/code/foreign-load.lisp
index ada107c36..4510f2ccf 100644
--- a/src/code/foreign-load.lisp
+++ b/src/code/foreign-load.lisp
@@ -48,7 +48,7 @@ (defun load-shared-object (pathname &key dont-save)
 definitions; if a symbol was previously referenced through the object and
 is not present in the reloaded version an error will be signalled. Reloading
 may not work as expected if user or library-code has called dlopen(3) on the
-same shared object.
+same shared object or running on a system where dlclose(3) is a noop.
 
 LOAD-SHARED-OBJECT interacts with SB-EXT:SAVE-LISP-AND-DIE:
 
diff --git a/tests/foreign.test.sh b/tests/foreign.test.sh
index fabba1246..53131bdd2 100755
--- a/tests/foreign.test.sh
+++ b/tests/foreign.test.sh
@@ -140,6 +140,28 @@ echo 'int late_foo = 43;' > $TEST_FILESTEM-c.c
 echo 'int late_bar() { return 14; }' >> $TEST_FILESTEM-c.c
 build_so $TEST_FILESTEM-c
 
+cat > $TEST_FILESTEM-noop-dlclose-test.c <<EOF
+#include <dlfcn.h>
+#include <stddef.h>
+
+int dlclose_is_noop () {
+    void * handle = dlopen("./$TEST_FILESTEM-noop-dlclose-test-helper.so", RTLD_NOW | RTLD_GLOBAL);
+    dlclose(handle);
+
+    handle = dlopen("./$TEST_FILESTEM-noop-dlclose-test-helper.so", RTLD_NOW | RTLD_NOLOAD);
+    if (handle != NULL) {
+        return 1;
+    }
+    return 0;
+}
+EOF
+build_so $TEST_FILESTEM-noop-dlclose-test
+
+cat > $TEST_FILESTEM-noop-dlclose-test-helper.c <<EOF
+int sbcl_dlclose_test = 42;
+EOF
+build_so $TEST_FILESTEM-noop-dlclose-test-helper
+
 ## Foreign definitions & load
 
 cat > $TEST_FILESTEM.base.lisp <<EOF
@@ -246,20 +268,28 @@ cat > $TEST_FILESTEM.test.lisp <<EOF
 
   (note "/initial assertions ok")
 
+  ;; determine if dlclose is a noop.
+  (load-shared-object (truename "$TEST_FILESTEM-noop-dlclose-test.so"))
+  (define-alien-routine dlclose-is-noop int)
+  (defparameter *dlclose-noop-p* (plusp (dlclose-is-noop)))
+
   ;; test reloading object file with new definitions
   (assert (= 13 foo))
   (assert (= 42 (bar)))
   (note "/original definitions ok")
-  (rename-file "$TEST_FILESTEM-b.so" "$TEST_FILESTEM-b.bak")
-  (rename-file "$TEST_FILESTEM-b2.so" "$TEST_FILESTEM-b.so")
-  (load-shared-object (truename "$TEST_FILESTEM-b.so"))
-  (note "/reloading ok")
-  (assert (= 42 foo))
-  (assert (= 13 (bar)))
-  (note "/redefined versions ok")
-  (rename-file "$TEST_FILESTEM-b.so" "$TEST_FILESTEM-b2.so")
-  (rename-file "$TEST_FILESTEM-b.bak" "$TEST_FILESTEM-b.so")
-  (note "/renamed back to originals")
+  (if *dlclose-noop-p*
+      (note "/skipping reloading tests")
+      (progn
+        (rename-file "$TEST_FILESTEM-b.so" "$TEST_FILESTEM-b.bak")
+        (rename-file "$TEST_FILESTEM-b2.so" "$TEST_FILESTEM-b.so")
+        (load-shared-object (truename "$TEST_FILESTEM-b.so"))
+        (note "/reloading ok")
+        (assert (= 42 foo))
+        (assert (= 13 (bar)))
+        (note "/redefined versions ok")
+        (rename-file "$TEST_FILESTEM-b.so" "$TEST_FILESTEM-b2.so")
+        (rename-file "$TEST_FILESTEM-b.bak" "$TEST_FILESTEM-b.so")
+        (note "/renamed back to originals")))
 
   ;; test late resolution
   #+linkage-table
@@ -276,13 +306,16 @@ cat > $TEST_FILESTEM.test.lisp <<EOF
     (load-shared-object (truename "$TEST_FILESTEM-c.so"))
     (assert (= 43 late-foo))
     (assert (= 14 (late-bar)))
-    (unload-shared-object (truename "$TEST_FILESTEM-c.so"))
-    (multiple-value-bind (val err) (ignore-errors late-foo)
-      (assert (not val))
-      (assert (typep err 'undefined-alien-error)))
-    (multiple-value-bind (val err) (ignore-errors (late-bar))
-      (assert (not val))
-      (assert (typep err 'undefined-alien-error)))
+    (if *dlclose-noop-p*
+        (note "/skipping linkage table unloading tests")
+        (progn
+          (unload-shared-object (truename "$TEST_FILESTEM-c.so"))
+          (multiple-value-bind (val err) (ignore-errors late-foo)
+            (assert (not val))
+            (assert (typep err 'undefined-alien-error)))
+          (multiple-value-bind (val err) (ignore-errors (late-bar))
+            (assert (not val))
+            (assert (typep err 'undefined-alien-error)))))
     (note "/linkage table ok"))
 
   (sb-ext:exit :code $EXIT_LISP_WIN) ; success convention for Lisp program
-- 
2.25.0