aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/testdata
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/testdata')
-rw-r--r--src/runtime/testdata/testprog/checkptr.go36
-rw-r--r--src/runtime/testdata/testprogcgo/tracebackctxt.go33
-rw-r--r--src/runtime/testdata/testprogcgo/tracebackctxt_c.c14
3 files changed, 79 insertions, 4 deletions
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index f76b64ad96..9c5561396e 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -4,11 +4,16 @@
package main
-import "unsafe"
+import (
+ "runtime"
+ "time"
+ "unsafe"
+)
func init() {
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
+ register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr)
register("CheckPtrArithmetic", CheckPtrArithmetic)
register("CheckPtrArithmetic2", CheckPtrArithmetic2)
register("CheckPtrSize", CheckPtrSize)
@@ -29,6 +34,35 @@ func CheckPtrAlignmentPtr() {
sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
}
+// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash
+// on nil pointers (#47430).
+func CheckPtrAlignmentNilPtr() {
+ var do func(int)
+ do = func(n int) {
+ // Inflate the stack so runtime.shrinkstack gets called during GC
+ if n > 0 {
+ do(n - 1)
+ }
+
+ var p unsafe.Pointer
+ _ = (*int)(p)
+ }
+
+ go func() {
+ for {
+ runtime.GC()
+ }
+ }()
+
+ go func() {
+ for i := 0; ; i++ {
+ do(i % 1024)
+ }
+ }()
+
+ time.Sleep(time.Second)
+}
+
func CheckPtrArithmetic() {
var x int
i := uintptr(unsafe.Pointer(&x))
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt.go b/src/runtime/testdata/testprogcgo/tracebackctxt.go
index 51fa4ad25c..62ff8eccd6 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt.go
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The __attribute__((weak)) used below doesn't seem to work on Windows.
-
package main
// Test the context argument to SetCgoTraceback.
@@ -14,20 +12,24 @@ package main
extern void C1(void);
extern void C2(void);
extern void tcContext(void*);
+extern void tcContextSimple(void*);
extern void tcTraceback(void*);
extern void tcSymbolizer(void*);
extern int getContextCount(void);
+extern void TracebackContextPreemptionCallGo(int);
*/
import "C"
import (
"fmt"
"runtime"
+ "sync"
"unsafe"
)
func init() {
register("TracebackContext", TracebackContext)
+ register("TracebackContextPreemption", TracebackContextPreemption)
}
var tracebackOK bool
@@ -105,3 +107,30 @@ wantLoop:
tracebackOK = false
}
}
+
+// Issue 47441.
+func TracebackContextPreemption() {
+ runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
+
+ const funcs = 10
+ const calls = 1e5
+ var wg sync.WaitGroup
+ for i := 0; i < funcs; i++ {
+ wg.Add(1)
+ go func(i int) {
+ defer wg.Done()
+ for j := 0; j < calls; j++ {
+ C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
+ }
+ }(i)
+ }
+ wg.Wait()
+
+ fmt.Println("OK")
+}
+
+//export TracebackContextPreemptionGoFunction
+func TracebackContextPreemptionGoFunction(i C.int) {
+ // Do some busy work.
+ fmt.Sprintf("%d\n", i)
+}
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
index 900cada0d3..910cb7b899 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
@@ -11,6 +11,7 @@
// Functions exported from Go.
extern void G1(void);
extern void G2(void);
+extern void TracebackContextPreemptionGoFunction(int);
void C1() {
G1();
@@ -62,10 +63,17 @@ void tcContext(void* parg) {
}
}
+void tcContextSimple(void* parg) {
+ struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
+ if (arg->context == 0) {
+ arg->context = 1;
+ }
+}
+
void tcTraceback(void* parg) {
int base, i;
struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
- if (arg->context == 0) {
+ if (arg->context == 0 && arg->sigContext == 0) {
// This shouldn't happen in this program.
abort();
}
@@ -89,3 +97,7 @@ void tcSymbolizer(void *parg) {
arg->func = "cFunction";
arg->lineno = arg->pc + (arg->more << 16);
}
+
+void TracebackContextPreemptionCallGo(int i) {
+ TracebackContextPreemptionGoFunction(i);
+}