diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/cmd/go/internal/bug | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/go/internal/bug')
-rw-r--r-- | src/cmd/go/internal/bug/bug.go | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/src/cmd/go/internal/bug/bug.go b/src/cmd/go/internal/bug/bug.go new file mode 100644 index 0000000..4aa08b4 --- /dev/null +++ b/src/cmd/go/internal/bug/bug.go @@ -0,0 +1,211 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package bug implements the ``go bug'' command. +package bug + +import ( + "bytes" + "context" + "fmt" + exec "internal/execabs" + "io" + urlpkg "net/url" + "os" + "path/filepath" + "regexp" + "runtime" + "strings" + + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/web" +) + +var CmdBug = &base.Command{ + Run: runBug, + UsageLine: "go bug", + Short: "start a bug report", + Long: ` +Bug opens the default browser and starts a new bug report. +The report includes useful system information. + `, +} + +func init() { + CmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "") +} + +func runBug(ctx context.Context, cmd *base.Command, args []string) { + if len(args) > 0 { + base.Fatalf("go bug: bug takes no arguments") + } + var buf bytes.Buffer + buf.WriteString(bugHeader) + printGoVersion(&buf) + buf.WriteString("### Does this issue reproduce with the latest release?\n\n\n") + printEnvDetails(&buf) + buf.WriteString(bugFooter) + + body := buf.String() + url := "https://github.com/golang/go/issues/new?body=" + urlpkg.QueryEscape(body) + if !web.OpenBrowser(url) { + fmt.Print("Please file a new issue at golang.org/issue/new using this template:\n\n") + fmt.Print(body) + } +} + +const bugHeader = `<!-- Please answer these questions before submitting your issue. Thanks! --> + +` +const bugFooter = `### What did you do? + +<!-- +If possible, provide a recipe for reproducing the error. +A complete runnable program is good. +A link on play.golang.org is best. +--> + + + +### What did you expect to see? + + + +### What did you see instead? + +` + +func printGoVersion(w io.Writer) { + fmt.Fprintf(w, "### What version of Go are you using (`go version`)?\n\n") + fmt.Fprintf(w, "<pre>\n") + fmt.Fprintf(w, "$ go version\n") + printCmdOut(w, "", "go", "version") + fmt.Fprintf(w, "</pre>\n") + fmt.Fprintf(w, "\n") +} + +func printEnvDetails(w io.Writer) { + fmt.Fprintf(w, "### What operating system and processor architecture are you using (`go env`)?\n\n") + fmt.Fprintf(w, "<details><summary><code>go env</code> Output</summary><br><pre>\n") + fmt.Fprintf(w, "$ go env\n") + printCmdOut(w, "", "go", "env") + printGoDetails(w) + printOSDetails(w) + printCDetails(w) + fmt.Fprintf(w, "</pre></details>\n\n") +} + +func printGoDetails(w io.Writer) { + printCmdOut(w, "GOROOT/bin/go version: ", filepath.Join(runtime.GOROOT(), "bin/go"), "version") + printCmdOut(w, "GOROOT/bin/go tool compile -V: ", filepath.Join(runtime.GOROOT(), "bin/go"), "tool", "compile", "-V") +} + +func printOSDetails(w io.Writer) { + switch runtime.GOOS { + case "darwin", "ios": + printCmdOut(w, "uname -v: ", "uname", "-v") + printCmdOut(w, "", "sw_vers") + case "linux": + printCmdOut(w, "uname -sr: ", "uname", "-sr") + printCmdOut(w, "", "lsb_release", "-a") + printGlibcVersion(w) + case "openbsd", "netbsd", "freebsd", "dragonfly": + printCmdOut(w, "uname -v: ", "uname", "-v") + case "illumos", "solaris": + // Be sure to use the OS-supplied uname, in "/usr/bin": + printCmdOut(w, "uname -srv: ", "/usr/bin/uname", "-srv") + out, err := os.ReadFile("/etc/release") + if err == nil { + fmt.Fprintf(w, "/etc/release: %s\n", out) + } else { + if cfg.BuildV { + fmt.Printf("failed to read /etc/release: %v\n", err) + } + } + } +} + +func printCDetails(w io.Writer) { + printCmdOut(w, "lldb --version: ", "lldb", "--version") + cmd := exec.Command("gdb", "--version") + out, err := cmd.Output() + if err == nil { + // There's apparently no combination of command line flags + // to get gdb to spit out its version without the license and warranty. + // Print up to the first newline. + fmt.Fprintf(w, "gdb --version: %s\n", firstLine(out)) + } else { + if cfg.BuildV { + fmt.Printf("failed to run gdb --version: %v\n", err) + } + } +} + +// printCmdOut prints the output of running the given command. +// It ignores failures; 'go bug' is best effort. +func printCmdOut(w io.Writer, prefix, path string, args ...string) { + cmd := exec.Command(path, args...) + out, err := cmd.Output() + if err != nil { + if cfg.BuildV { + fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err) + } + return + } + fmt.Fprintf(w, "%s%s\n", prefix, bytes.TrimSpace(out)) +} + +// firstLine returns the first line of a given byte slice. +func firstLine(buf []byte) []byte { + idx := bytes.IndexByte(buf, '\n') + if idx > 0 { + buf = buf[:idx] + } + return bytes.TrimSpace(buf) +} + +// printGlibcVersion prints information about the glibc version. +// It ignores failures. +func printGlibcVersion(w io.Writer) { + tempdir := os.TempDir() + if tempdir == "" { + return + } + src := []byte(`int main() {}`) + srcfile := filepath.Join(tempdir, "go-bug.c") + outfile := filepath.Join(tempdir, "go-bug") + err := os.WriteFile(srcfile, src, 0644) + if err != nil { + return + } + defer os.Remove(srcfile) + cmd := exec.Command("gcc", "-o", outfile, srcfile) + if _, err = cmd.CombinedOutput(); err != nil { + return + } + defer os.Remove(outfile) + + cmd = exec.Command("ldd", outfile) + out, err := cmd.CombinedOutput() + if err != nil { + return + } + re := regexp.MustCompile(`libc\.so[^ ]* => ([^ ]+)`) + m := re.FindStringSubmatch(string(out)) + if m == nil { + return + } + cmd = exec.Command(m[1]) + out, err = cmd.Output() + if err != nil { + return + } + fmt.Fprintf(w, "%s: %s\n", m[1], firstLine(out)) + + // print another line (the one containing version string) in case of musl libc + if idx := bytes.IndexByte(out, '\n'); bytes.Index(out, []byte("musl")) != -1 && idx > -1 { + fmt.Fprintf(w, "%s\n", firstLine(out[idx+1:])) + } +} |