-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/compile: does not check go:writebarrierrec for print functions #34014
Comments
Thanks for this report @ianlancetaylor! I think this issue might show a symptom that With degree 1This is similar to manually adding diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 6a8b5b7ace..46f4b27f3f 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -229,6 +229,20 @@ func clearSignalHandlers() {
}
}
+//go:nowritebarrierrec
+func f1(x *[]byte, y *[]byte) {
+ foo(x, y)
+}
+
+func f2() {
+ var x, y []byte
+ foo(&x, &y)
+}
+
+func foo(x *[]byte, y *[]byte) {
+ *x = *y
+}
+ and on running $ GO111MODULE=off go get .
# runtime
./signal_unix.go:234:8: write barrier prohibited
./signal_unix.go:234:8: write barrier prohibited by caller; f1 With degree 2 of connection, inlining enableddiff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 6a8b5b7ace..4aaf4cef87 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -229,6 +229,21 @@ func clearSignalHandlers() {
}
}
+//go:nowritebarrierrec
+func f1(x *[]byte, y *[]byte) []byte {
+ return f2()
+}
+
+func f2() []byte {
+ var x, y []byte
+ return foo(&x, &y)
+}
+
+func foo(x *[]byte, y *[]byte) []byte{
+ *x = *y
+ return *x
+}
+ when run doesn't print any error. GO111MODULE=off go get . With degree 2 and disabled inliningdiff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 6a8b5b7ace..4aaf4cef87 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -229,6 +229,21 @@ func clearSignalHandlers() {
}
}
+//go:nowritebarrierrec
+func f1(x *[]byte, y *[]byte) []byte {
+ return f2()
+}
+
+func f2() []byte {
+ var x, y []byte
+ return foo(&x, &y)
+}
+
+func foo(x *[]byte, y *[]byte) []byte{
+ *x = *y
+ return *x
+}
+ $ GO111MODULE=off go get -gcflags='-l' .
# runtime
./signal_unix.go:243:8: write barrier prohibited by caller; foo
/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/runtime/signal_unix.go:239:15: called by f2
/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/runtime/signal_unix.go:234:14: called by f1 Please re-attempt your experiment with the |
My apologies, my analysis is totally unrelated to your problem @ianlancetaylor! Regardless of if I use diff --git a/src/runtime/print.go b/src/runtime/print.go
index e605eb34cb..29ea1a864b 100644
--- a/src/runtime/print.go
+++ b/src/runtime/print.go
@@ -238,7 +238,10 @@ func printpointer(p unsafe.Pointer) {
printhex(uint64(uintptr(p)))
}
+var z string
+
func printstring(s string) {
+ z = s
gwrite(bytes(s))
} Unless I also manually set |
@odeke-em, just to close the loop on your examples, your "With degree 2 of connection, inlining enabled" example doesn't fail because there's actually no write barrier under |
Got it, thank you @aclements! |
The runtime function
sighandler
is markedgo:nowritebarrierrec
. It callsprint
which cmd/compile turns into calls toprintstring
and friends. However, if I modifyprintstring
to force a write barrier, no error is issued when compiling the runtime package. If I then markprintstring
asgo:nowritebarrierrec
, I do get an error. My conclusion from this is that cmd/compile does not applygo:nowritebarrierrec
to the calls generated by calling theprint
function.I believe this is because in
(*nowritebarrierrecChecker).check
theprintstring
functions are never added to thesymToFunc
map.CC @aclements
The text was updated successfully, but these errors were encountered: