Commit 95433de3 authored by Kirill Smelkov's avatar Kirill Smelkov

tracing/runtime: Add support for Go1.21 (2/2)

Fix StopTheWorld crash due to change in runtime.stopTheWorld signature:

In Go1.21 stopTheWorld changed from accepting reason as string into
accepting reason as uint8 code:

    https://github.com/golang/go/commit/b1aadd034c1f
    https://golang.org/cl/494495

which leads to the following crash if reason is still passed as string:

    fatal error: index out of range

    goroutine 6 [running]:
    runtime.throw({0x531aad?, 0x0?})
    	/home/kirr/src/tools/go/go/src/runtime/panic.go:1077 +0x5c fp=0xc000042608 sp=0xc0000425d8 pc=0x4365bc
    runtime.panicCheck1(0x4785af?, {0x531aad, 0x12})
    	/home/kirr/src/tools/go/go/src/runtime/panic.go:58 +0x94 fp=0xc000042628 sp=0xc000042608 pc=0x434034
    runtime.goPanicIndex(0x8d, 0x11)
    	/home/kirr/src/tools/go/go/src/runtime/panic.go:113 +0x2e fp=0xc000042668 sp=0xc000042628 pc=0x4340ee
    runtime.stwReason.String(...)
    	/home/kirr/src/tools/go/go/src/runtime/proc.go:1217
    runtime.stopTheWorld(0x8d)
    	/home/kirr/src/tools/go/go/src/runtime/proc.go:1260 +0xe6 fp=0xc0000426c8 sp=0xc000042668 pc=0x43b3a6
    lab.nexedi.com/kirr/go123/tracing/internal/xruntime.StopTheWorld(...)
    	/home/kirr/src/neo/src/lab.nexedi.com/kirr/go123/tracing/internal/xruntime/runtime.go:40
    lab.nexedi.com/kirr/go123/tracing/internal/xruntime.TestStartStopTheWorld(0xc000007860)
    	/home/kirr/src/neo/src/lab.nexedi.com/kirr/go123/tracing/internal/xruntime/runtime_test.go:75 +0x139 fp=0xc000042770 sp=0xc0000426c8 pc=0x4fa0f9
    testing.tRunner(0xc000007860, 0x53a8b8)
    	/home/kirr/src/tools/go/go/src/testing/testing.go:1595 +0xff fp=0xc0000427c0 sp=0xc000042770 pc=0x4bbd9f
    testing.(*T).Run.func1()
    	/home/kirr/src/tools/go/go/src/testing/testing.go:1648 +0x25 fp=0xc0000427e0 sp=0xc0000427c0 pc=0x4bcd25
    runtime.goexit()
    	/home/kirr/src/tools/go/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc0000427e8 sp=0xc0000427e0 pc=0x468901
    created by testing.(*T).Run in goroutine 1
    	/home/kirr/src/tools/go/go/src/testing/testing.go:1648 +0x3ad

-> Fix it by accounting that STW reason is uint8 on go1.21 and passing it
to runtime correspondingly.

Sadly we cannot express arbitrary string reason into fixed list of
reasons that runtime and stdlib tracing are aware of, so we always use
"unknown" for custom stop-the-world requests.
parent 3a209cd1
// Copyright (C) 2016-2017 Nexedi SA and Contributors.
// Copyright (C) 2016-2023 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -21,14 +21,6 @@ package xruntime
// stop-the-world that should probably be in public xruntime, but I'm (yet)
// hesitating to expose the API to public.
import _ "unsafe"
//go:linkname runtime_stopTheWorld runtime.stopTheWorld
//go:linkname runtime_startTheWorld runtime.startTheWorld
func runtime_stopTheWorld(reason string)
func runtime_startTheWorld()
// StopTheWorld returns with the world stopped.
//
// Current goroutine remains the only one who is running, with others
......@@ -37,10 +29,10 @@ func runtime_startTheWorld()
// fatal errors when the world is stopped - for example using timers would be
// invalid, but adjusting plain values in memory is ok.
func StopTheWorld(reason string) {
runtime_stopTheWorld(reason)
stopTheWorld(reason)
}
// StartTheWorld restarts the world after it was stopped by StopTheWorld.
func StartTheWorld() {
runtime_startTheWorld()
startTheWorld()
}
// Copyright (C) 2016-2023 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
//go:build !go1.21
// +build !go1.21
package xruntime
import _ "unsafe"
//go:linkname runtime_stopTheWorld runtime.stopTheWorld
//go:linkname runtime_startTheWorld runtime.startTheWorld
func runtime_stopTheWorld(reason string)
func runtime_startTheWorld()
func stopTheWorld(reason string) {
runtime_stopTheWorld(reason)
}
func startTheWorld() {
runtime_startTheWorld()
}
// Copyright (C) 2016-2023 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
//go:build go1.21
// +build go1.21
package xruntime
import _ "unsafe"
//go:linkname runtime_stopTheWorld runtime.stopTheWorld
//go:linkname runtime_startTheWorld runtime.startTheWorld
type stwReason uint8
func runtime_stopTheWorld(reason stwReason)
func runtime_startTheWorld()
func stopTheWorld(reason string) {
runtime_stopTheWorld(0) // cannot express arbitrary string reason as code; stop with "unknown"
}
func startTheWorld() {
runtime_startTheWorld()
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment