1 // Portions copyright 2009 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 // Package debug is a very partially implemented package to allow compilation.
6 package debug
7 8 import (
9 "fmt"
10 "runtime"
11 "strconv"
12 "bytes"
13 )
14 15 // SetMaxStack sets the maximum amount of memory that can be used by a single
16 // goroutine stack.
17 //
18 // Not implemented.
19 func SetMaxStack(n int) int {
20 return n
21 }
22 23 // PrintStack prints to standard error the stack trace returned by runtime.Stack.
24 //
25 // Not implemented.
26 func PrintStack() {}
27 28 // Stack returns a formatted stack trace of the goroutine that calls it.
29 //
30 // Not implemented.
31 func Stack() []byte {
32 return nil
33 }
34 35 // ReadBuildInfo returns the build information embedded
36 // in the running binary. The information is available only
37 // in binaries built with module support.
38 //
39 // Not implemented.
40 func ReadBuildInfo() (info *BuildInfo, ok bool) {
41 return &BuildInfo{GoVersion: runtime.Compiler + runtime.Version()}, true
42 }
43 44 // BuildInfo represents the build information read from
45 // the running binary.
46 type BuildInfo struct {
47 GoVersion string // version of the Go toolchain that built the binary, e.g. "go1.19.2"
48 Path string // The main package path
49 Main Module // The module containing the main package
50 Deps []*Module // Module dependencies
51 Settings []BuildSetting
52 }
53 54 type BuildSetting struct {
55 // Key and Value describe the build setting.
56 // Key must not contain an equals sign, space, tab, or newline.
57 // Value must not contain newlines ('\n').
58 Key, Value string
59 }
60 61 // Module represents a module.
62 type Module struct {
63 Path string // module path
64 Version string // module version
65 Sum string // checksum
66 Replace *Module // replaced by this module
67 }
68 69 // Not implemented.
70 func SetGCPercent(n int) int {
71 return n
72 }
73 74 // Start of stolen from big go. TODO: import/reuse without copy pasta.
75 76 // quoteKey reports whether key is required to be quoted.
77 func quoteKey(key string) bool {
78 return len(key) == 0 || bytes.ContainsAny(key, "= \t\r\n\"`")
79 }
80 81 // quoteValue reports whether value is required to be quoted.
82 func quoteValue(value string) bool {
83 return bytes.ContainsAny(value, " \t\r\n\"`")
84 }
85 86 func (bi *BuildInfo) String() string {
87 buf := new(bytes.Buffer)
88 if bi.GoVersion != "" {
89 fmt.Fprintf(buf, "go\t%s\n", bi.GoVersion)
90 }
91 if bi.Path != "" {
92 fmt.Fprintf(buf, "path\t%s\n", bi.Path)
93 }
94 var formatMod func(string, Module)
95 formatMod = func(word string, m Module) {
96 buf.WriteString(word)
97 buf.WriteByte('\t')
98 buf.WriteString(m.Path)
99 buf.WriteByte('\t')
100 buf.WriteString(m.Version)
101 if m.Replace == nil {
102 buf.WriteByte('\t')
103 buf.WriteString(m.Sum)
104 } else {
105 buf.WriteByte('\n')
106 formatMod("=>", *m.Replace)
107 }
108 buf.WriteByte('\n')
109 }
110 if bi.Main != (Module{}) {
111 formatMod("mod", bi.Main)
112 }
113 for _, dep := range bi.Deps {
114 formatMod("dep", *dep)
115 }
116 for _, s := range bi.Settings {
117 key := s.Key
118 if quoteKey(key) {
119 key = strconv.Quote(key)
120 }
121 value := s.Value
122 if quoteValue(value) {
123 value = strconv.Quote(value)
124 }
125 fmt.Fprintf(buf, "build\t%s=%s\n", key, value)
126 }
127 128 return buf.String()
129 }
130