Skip to content

Commit aae7734

Browse files
committed
internal/trace/v2: tolerate having a P in GoCreateSyscall
On non-pthread platforms, it's totally possible for the same M to GoCreateSyscall/GoDestroySyscall on the same thread multiple times. That same thread may hold onto its P through all those calls. For #64060. Change-Id: Ib968bfd439ecd5bc24fc98d78c06145b0d4b7802 Reviewed-on: https://go-review.googlesource.com/c/go/+/545515 Reviewed-by: Michael Pratt <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent b2efd1d commit aae7734

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

src/internal/trace/v2/order.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ func (o *ordering) advance(ev *baseEvent, evt *evTable, m ThreadID, gen uint64)
485485
// This event indicates that a goroutine is effectively
486486
// being created out of a cgo callback. Such a goroutine
487487
// is 'created' in the syscall state.
488-
if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MustNotHave, Goroutine: event.MustNotHave}); err != nil {
488+
if err := validateCtx(curCtx, event.SchedReqs{Thread: event.MustHave, Proc: event.MayHave, Goroutine: event.MustNotHave}); err != nil {
489489
return curCtx, false, err
490490
}
491491
// This goroutine is effectively being created. Add a state for it.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2023 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+
// Tests a G being created from within a syscall.
6+
//
7+
// Specifically, it tests a scenerio wherein a C
8+
// thread is calling into Go, creating a goroutine in
9+
// a syscall (in the tracer's model). Because the actual
10+
// m can be reused, it's possible for that m to have never
11+
// had its P (in _Psyscall) stolen.
12+
//
13+
// This is a regression test. The trace parser once required
14+
// GoCreateSyscall to not have a P, but it can in the scenario
15+
// described above.
16+
17+
package main
18+
19+
import (
20+
"internal/trace/v2"
21+
"internal/trace/v2/event/go122"
22+
testgen "internal/trace/v2/internal/testgen/go122"
23+
)
24+
25+
func main() {
26+
testgen.Main(gen)
27+
}
28+
29+
func gen(t *testgen.Trace) {
30+
t.DisableTimestamps()
31+
32+
g := t.Generation(1)
33+
34+
// A C thread calls into Go and acquires a P. It returns
35+
// back to C, destroying the G. It then comes back to Go
36+
// on the same thread and again returns to C.
37+
//
38+
// Note: on pthread platforms this can't happen on the
39+
// same thread because the m is stashed in TLS between
40+
// calls into Go, until the thread dies. This is still
41+
// possible on other platforms, however.
42+
b0 := g.Batch(trace.ThreadID(0), 0)
43+
b0.Event("GoCreateSyscall", trace.GoID(4))
44+
b0.Event("ProcStatus", trace.ProcID(0), go122.ProcIdle)
45+
b0.Event("ProcStart", trace.ProcID(0), testgen.Seq(1))
46+
b0.Event("GoSyscallEndBlocked")
47+
b0.Event("GoStart", trace.GoID(4), testgen.Seq(1))
48+
b0.Event("GoSyscallBegin", testgen.Seq(2), testgen.NoStack)
49+
b0.Event("GoDestroySyscall")
50+
b0.Event("GoCreateSyscall", trace.GoID(4))
51+
b0.Event("GoSyscallEnd")
52+
b0.Event("GoSyscallBegin", testgen.Seq(3), testgen.NoStack)
53+
b0.Event("GoDestroySyscall")
54+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- expect --
2+
SUCCESS
3+
-- trace --
4+
Trace Go1.22
5+
EventBatch gen=1 m=0 time=0 size=34
6+
GoCreateSyscall dt=0 new_g=4
7+
ProcStatus dt=0 p=0 pstatus=2
8+
ProcStart dt=0 p=0 p_seq=1
9+
GoSyscallEndBlocked dt=0
10+
GoStart dt=0 g=4 g_seq=1
11+
GoSyscallBegin dt=0 p_seq=2 stack=0
12+
GoDestroySyscall dt=0
13+
GoCreateSyscall dt=0 new_g=4
14+
GoSyscallEnd dt=0
15+
GoSyscallBegin dt=0 p_seq=3 stack=0
16+
GoDestroySyscall dt=0
17+
EventBatch gen=1 m=18446744073709551615 time=0 size=5
18+
Frequency freq=15625000
19+
EventBatch gen=1 m=18446744073709551615 time=0 size=1
20+
Stacks
21+
EventBatch gen=1 m=18446744073709551615 time=0 size=1
22+
Strings

0 commit comments

Comments
 (0)