]> Cypherpunks repositories - gostls13.git/commitdiff
internal/trace/v2: forward Event.Stack to StateTransition.Stack
authorMichael Anthony Knyszek <mknyszek@google.com>
Tue, 21 Nov 2023 17:23:43 +0000 (17:23 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 21 Nov 2023 20:45:09 +0000 (20:45 +0000)
Currently StateTransition.Stack is only set for the GoCreate case,
because there are two stacks and we need to distinguish them. But the
docs for StateTransition.Stack say that that stack always references the
resource that is transitioning. There are quite a few cases where
Event.Stack is actually the appropriate stack to for
StateTransition.Stack, but in these cases it's left empty, and the
caller just needs to understand which one to look at. This isn't great.
Forward Event.Stack to StateTransition.Stack whenever Event.Stack also
refers to the resource experiencing the state transition.

Change-Id: Ie43fc6036f2712c7982174d5739d95765312dfcc
Reviewed-on: https://go-review.googlesource.com/c/go/+/544316
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/internal/trace/v2/event.go
src/internal/trace/v2/testtrace/validation.go

index 7ec4698d88d98a67f2232ad1073e4e1f5b80adea..3700cbcc2f8775da4cd5635b8ea6ffa925963161 100644 (file)
@@ -568,22 +568,28 @@ func (e Event) StateTransition() StateTransition {
                s = goStateTransition(GoID(e.base.args[0]), GoRunnable, GoRunning)
        case go122.EvGoDestroy:
                s = goStateTransition(e.ctx.G, GoRunning, GoNotExist)
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoDestroySyscall:
                s = goStateTransition(e.ctx.G, GoSyscall, GoNotExist)
        case go122.EvGoStop:
                s = goStateTransition(e.ctx.G, GoRunning, GoRunnable)
                s.Reason = e.table.strings.mustGet(stringID(e.base.args[0]))
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoBlock:
                s = goStateTransition(e.ctx.G, GoRunning, GoWaiting)
                s.Reason = e.table.strings.mustGet(stringID(e.base.args[0]))
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoUnblock:
                s = goStateTransition(GoID(e.base.args[0]), GoWaiting, GoRunnable)
        case go122.EvGoSyscallBegin:
                s = goStateTransition(e.ctx.G, GoRunning, GoSyscall)
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoSyscallEnd:
                s = goStateTransition(e.ctx.G, GoSyscall, GoRunning)
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoSyscallEndBlocked:
                s = goStateTransition(e.ctx.G, GoSyscall, GoRunnable)
+               s.Stack = e.Stack() // This event references the resource the event happened on.
        case go122.EvGoStatus:
                // N.B. ordering.advance populates e.base.extra.
                s = goStateTransition(GoID(e.base.args[0]), GoState(e.base.extra(version.Go122)[0]), go122GoStatus2GoState[e.base.args[2]])
index fcbc10801b5e0ef099e8a64f2786d4e64efbea5b..a2654a10e4e8b7c2b06e3d972fcd2c10a1a0aa2d 100644 (file)
@@ -169,6 +169,11 @@ func (v *Validator) Event(ev trace.Event) error {
                                        state.binding = ctx
                                }
                        } else if old.Executing() && !new.Executing() {
+                               if tr.Stack != ev.Stack() {
+                                       // This is a case where the transition is happening to a goroutine that is also executing, so
+                                       // these two stacks should always match.
+                                       e.Errorf("StateTransition.Stack doesn't match Event.Stack")
+                               }
                                ctx := state.binding
                                if ctx != nil {
                                        if ctx.G != id {