Skip to content

Commit

Permalink
0.9.8.38:
Browse files Browse the repository at this point in the history
        Log a BUG.
  • Loading branch information
jsnell committed Jan 13, 2006
1 parent d8ff33b commit 944adaa
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
28 changes: 28 additions & 0 deletions BUGS
Expand Up @@ -2122,3 +2122,31 @@ WORKAROUND:
(force-output)
(sb-ext:gc))))
(sleep 1))))

398: GC-unsafe SB-ALIEN string deporting
Translating a Lisp string to an alien string by taking a SAP to it
as done by the :DEPORT-GEN methods for C-STRING and UTF8-STRING
is not safe, since the Lisp string can move. For example the
following code will fail quickly on both cheneygc and pre-0.9.8.19
GENCGC:

(setf (bytes-consed-between-gcs) 4096)
(define-alien-routine "strcmp" int (s1 c-string) (s2 c-string))

(loop
(let ((string "hello, world"))
(assert (zerop (strcmp string string)))))

(This will appear to work on post-0.9.8.19 GENCGC, since
the GC no longer zeroes memory immediately after releasing
it after a minor GC. Either enabling the READ_PROTECT_FREE_PAGES
#define in gencgc.c or modifying the example so that a major
GC will occasionally be triggered would unmask the bug.)

On cheneygc the only solution would seem to be allocating some alien
memory, copying the data over, and arranging that it's freed once we
return. For GENCGC we could instead try to arrange that the string
from which the SAP is taken is always pinned.

For some more details see comments for (define-alien-type-method
(c-string :deport-gen) ...) in host-c-call.lisp.
26 changes: 26 additions & 0 deletions src/code/host-c-call.lisp
Expand Up @@ -36,7 +36,32 @@
`(etypecase ,value
(null (int-sap 0))
((alien (* char)) (alien-sap ,value))
;; FIXME: GC safety alert! These SAPs are not safe, since the
;; Lisp string can move. This is not hard to arrange, for example
;; the following will fail very quickly on a SB-UNICODE build:
;;
;; (setf (bytes-consed-between-gcs) 4096)
;; (define-alien-routine "strcmp" int (s1 c-string) (s2 c-string))
;;
;; (loop
;; (let ((string "hello, world"))
;; (assert (zerop (strcmp string string)))))
;;
;; (This will appear to work on post-0.9.8.19 GENCGC, since
;; the GC no longer zeroes memory immediately after releasing
;; it after a minor GC. Either enabling the READ_PROTECT_FREE_PAGES
;; #define in gencgc.c or modifying the example so that a major
;; GC will occasionally be triggered would unmask the bug).
;;
;; The SIMPLE-BASE-STRING case will generally be very hard to
;; trigger on GENCGC (even when threaded) thanks to GC
;; conservativeness. It's mostly a problem on cheneygc.
;; -- JES, 2006-01-13
(simple-base-string (vector-sap ,value))
;; This case, on the other hand, will cause trouble on GENCGC, since
;; we're taking the SAP of a immediately discarded temporary -> the
;; conservativeness doesn't protect us.
;; -- JES, 2006-01-13
(simple-string (vector-sap (coerce ,value 'simple-base-string)))))

(/show0 "host-c-call.lisp 42")
Expand Down Expand Up @@ -66,6 +91,7 @@
`(etypecase ,value
(null (int-sap 0))
((alien (* char)) (alien-sap ,value))
;; See the C-STRING :DEPORT-GEN comments for GC safety issues.
(simple-base-string (vector-sap ,value))
(simple-string (vector-sap (%deport-utf8-string ,value)))))

Expand Down
5 changes: 5 additions & 0 deletions src/code/target-c-call.lisp
Expand Up @@ -41,6 +41,11 @@
;;; appear to be vulnerable to the lisp string moving from underneath
;;; them if the world undergoes a GC, possibly triggered by another
;;; thread. Ugh.
;;;
;;; Actually the above shouldn't happen; x86 and x86-64 use GENCGC,
;;; so the string can't move by virtue of pointers to it from
;;; outside the heap. Other platforms will access the lisp string
;;; through the GC-safe interior pointer. -- JES, 2006-01-13
(defun %naturalize-c-string (sap)
(declare (type system-area-pointer sap))
(locally
Expand Down
2 changes: 1 addition & 1 deletion version.lisp-expr
Expand Up @@ -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.8.37"
"0.9.8.38"

0 comments on commit 944adaa

Please sign in to comment.