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 5package version 6 7import ( 8 "fmt" 9 "io" 10 11 "internal/trace/event" 12 "internal/trace/event/go122" 13) 14 15// Version represents the version of a trace file. 16type Version uint32 17 18const ( 19 Go111 Version = 11 20 Go119 Version = 19 21 Go121 Version = 21 22 Go122 Version = 22 23 Go123 Version = 23 24 Current = Go123 25) 26 27var versions = map[Version][]event.Spec{ 28 // Go 1.11–1.21 use a different parser and are only set here for the sake of 29 // Version.Valid. 30 Go111: nil, 31 Go119: nil, 32 Go121: nil, 33 34 Go122: go122.Specs(), 35 // Go 1.23 adds backwards-incompatible events, but 36 // traces produced by Go 1.22 are also always valid 37 // Go 1.23 traces. 38 Go123: go122.Specs(), 39} 40 41// Specs returns the set of event.Specs for this version. 42func (v Version) Specs() []event.Spec { 43 return versions[v] 44} 45 46func (v Version) Valid() bool { 47 _, ok := versions[v] 48 return ok 49} 50 51// headerFmt is the format of the header of all Go execution traces. 52const headerFmt = "go 1.%d trace\x00\x00\x00" 53 54// ReadHeader reads the version of the trace out of the trace file's 55// header, whose prefix must be present in v. 56func ReadHeader(r io.Reader) (Version, error) { 57 var v Version 58 _, err := fmt.Fscanf(r, headerFmt, &v) 59 if err != nil { 60 return v, fmt.Errorf("bad file format: not a Go execution trace?") 61 } 62 if !v.Valid() { 63 return v, fmt.Errorf("unknown or unsupported trace version go 1.%d", v) 64 } 65 return v, nil 66} 67 68// WriteHeader writes a header for a trace version v to w. 69func WriteHeader(w io.Writer, v Version) (int, error) { 70 return fmt.Fprintf(w, headerFmt, v) 71} 72