runtime: don't crash if no p in kickoff
The kickoff function for g0 can be invoked without a p, for example from mcall(exitsyscall0) in exitsyscall after exitsyscall has cleared the p field. The assignment gp.param = nil will invoke a write barrier. If gp.param is not already nil, this will require a p. Avoid the problem for a specific case that is known to be OK: when the value in gp.param is a *g. Reviewed-on: https://go-review.googlesource.com/46512 From-SVN: r249595
This commit is contained in:
parent
5f0b897b2e
commit
bb96aa6726
@ -1,4 +1,4 @@
|
|||||||
29c61dc3c5151df5de9362b7882ccf04679df976
|
f107cc8bced1939b0083231fc1ea24669ca4832c
|
||||||
|
|
||||||
The first line of this file holds the git revision number of the last
|
The first line of this file holds the git revision number of the last
|
||||||
merge done from the gofrontend repository.
|
merge done from the gofrontend repository.
|
||||||
|
@ -1097,7 +1097,25 @@ func kickoff() {
|
|||||||
fv := gp.entry
|
fv := gp.entry
|
||||||
param := gp.param
|
param := gp.param
|
||||||
gp.entry = nil
|
gp.entry = nil
|
||||||
|
|
||||||
|
// When running on the g0 stack we can wind up here without a p,
|
||||||
|
// for example from mcall(exitsyscall0) in exitsyscall.
|
||||||
|
// Setting gp.param = nil will call a write barrier, and if
|
||||||
|
// there is no p that write barrier will crash. When called from
|
||||||
|
// mcall the gp.param value will be a *g, which we don't need to
|
||||||
|
// shade since we know it will be kept alive elsewhere. In that
|
||||||
|
// case clear the field using uintptr so that the write barrier
|
||||||
|
// does nothing.
|
||||||
|
if gp.m.p == 0 {
|
||||||
|
if gp == gp.m.g0 && gp.param == unsafe.Pointer(gp.m.curg) {
|
||||||
|
*(*uintptr)(unsafe.Pointer(&gp.param)) = 0
|
||||||
|
} else {
|
||||||
|
throw("no p in kickoff")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gp.param = nil
|
gp.param = nil
|
||||||
|
|
||||||
fv(param)
|
fv(param)
|
||||||
goexit1()
|
goexit1()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user