Skip to content

Commit a90acc4

Browse files
runtime: Goexit on C-created thread report more useful error message
For #68275 Change-Id: Ic213a4e59aa24f125895946bf0001b82e55567bd
1 parent 9e8ea56 commit a90acc4

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

src/runtime/proc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4321,6 +4321,9 @@ func gdestroy(gp *g) {
43214321

43224322
if locked && mp.lockedInt != 0 {
43234323
print("runtime: mp.lockedInt = ", mp.lockedInt, "\n")
4324+
if mp.isextra {
4325+
throw("call runtime.Goexit in thread created during a not Go runtime")
4326+
}
43244327
throw("exited a goroutine internally locked to the OS thread")
43254328
}
43264329
gfput(pp, gp)

src/runtime/proc_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,3 +1158,10 @@ func TestBigGOMAXPROCS(t *testing.T) {
11581158
t.Errorf("output:\n%s\nwanted:\nunknown function: NonexistentTest", output)
11591159
}
11601160
}
1161+
1162+
func TestCgoToGoCallGoexit(t *testing.T) {
1163+
if runtime.GOOS != "windows" {
1164+
t.Skip("only test in Windows")
1165+
}
1166+
checkCoroTestProgOutput(t, runTestProg(t, "testprogcgo", "CgoToGoCallGoexit"))
1167+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build windows
6+
7+
package main
8+
9+
/*
10+
#include <pthread.h>
11+
12+
void go_callback();
13+
14+
static void *thr(void *arg) {
15+
go_callback();
16+
return 0;
17+
}
18+
19+
static void foo() {
20+
pthread_t th;
21+
pthread_attr_t attr;
22+
pthread_attr_init(&attr);
23+
pthread_attr_setstacksize(&attr, 256 << 10);
24+
pthread_create(&th, &attr, thr, 0);
25+
pthread_join(th, 0);
26+
}
27+
*/
28+
import "C"
29+
30+
import "runtime"
31+
32+
func init() {
33+
register("CgoToGoCallGoexit", func() {
34+
println("expect: call runtime.Goexit in thread created during a not Go runtime")
35+
CgoToGoCallGoexit()
36+
})
37+
}
38+
39+
func CgoToGoCallGoexit() {
40+
C.foo()
41+
}
42+
43+
//export go_callback
44+
func go_callback() {
45+
runtime.Goexit()
46+
}

0 commit comments

Comments
 (0)