mirror of
https://github.com/golang/go
synced 2024-10-02 18:18:33 -06:00
842b05832f
This change makes sure that tests are run with the correct version of the go tool. The correct version is the one that we invoked with "go test", not the one that is first in our path. Fixes #16577 Change-Id: If22c8f8c3ec9e7c35d094362873819f2fbb8559b Reviewed-on: https://go-review.googlesource.com/28089 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
263 lines
7.0 KiB
Go
263 lines
7.0 KiB
Go
// 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 runtime_test
|
|
|
|
import (
|
|
"debug/elf"
|
|
"debug/macho"
|
|
"encoding/binary"
|
|
"internal/testenv"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var lldbPath string
|
|
|
|
func checkLldbPython(t *testing.T) {
|
|
cmd := exec.Command("lldb", "-P")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Skipf("skipping due to issue running lldb: %v\n%s", err, out)
|
|
}
|
|
lldbPath = strings.TrimSpace(string(out))
|
|
|
|
cmd = exec.Command("/usr/bin/python2.7", "-c", "import sys;sys.path.append(sys.argv[1]);import lldb; print('go lldb python support')", lldbPath)
|
|
out, err = cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
t.Skipf("skipping due to issue running python: %v\n%s", err, out)
|
|
}
|
|
if string(out) != "go lldb python support\n" {
|
|
t.Skipf("skipping due to lack of python lldb support: %s", out)
|
|
}
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
// Try to see if we have debugging permissions.
|
|
cmd = exec.Command("/usr/sbin/DevToolsSecurity", "-status")
|
|
out, err = cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Skipf("DevToolsSecurity failed: %v", err)
|
|
} else if !strings.Contains(string(out), "enabled") {
|
|
t.Skip(string(out))
|
|
}
|
|
cmd = exec.Command("/usr/bin/groups")
|
|
out, err = cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Skipf("groups failed: %v", err)
|
|
} else if !strings.Contains(string(out), "_developer") {
|
|
t.Skip("Not in _developer group")
|
|
}
|
|
}
|
|
}
|
|
|
|
const lldbHelloSource = `
|
|
package main
|
|
import "fmt"
|
|
func main() {
|
|
mapvar := make(map[string]string,5)
|
|
mapvar["abc"] = "def"
|
|
mapvar["ghi"] = "jkl"
|
|
intvar := 42
|
|
ptrvar := &intvar
|
|
fmt.Println("hi") // line 10
|
|
_ = ptrvar
|
|
}
|
|
`
|
|
|
|
const lldbScriptSource = `
|
|
import sys
|
|
sys.path.append(sys.argv[1])
|
|
import lldb
|
|
import os
|
|
|
|
TIMEOUT_SECS = 5
|
|
|
|
debugger = lldb.SBDebugger.Create()
|
|
debugger.SetAsync(True)
|
|
target = debugger.CreateTargetWithFileAndArch("a.exe", None)
|
|
if target:
|
|
print "Created target"
|
|
main_bp = target.BreakpointCreateByLocation("main.go", 10)
|
|
if main_bp:
|
|
print "Created breakpoint"
|
|
process = target.LaunchSimple(None, None, os.getcwd())
|
|
if process:
|
|
print "Process launched"
|
|
listener = debugger.GetListener()
|
|
process.broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
|
|
while True:
|
|
event = lldb.SBEvent()
|
|
if listener.WaitForEvent(TIMEOUT_SECS, event):
|
|
if lldb.SBProcess.GetRestartedFromEvent(event):
|
|
continue
|
|
state = process.GetState()
|
|
if state in [lldb.eStateUnloaded, lldb.eStateLaunching, lldb.eStateRunning]:
|
|
continue
|
|
else:
|
|
print "Timeout launching"
|
|
break
|
|
if state == lldb.eStateStopped:
|
|
for t in process.threads:
|
|
if t.GetStopReason() == lldb.eStopReasonBreakpoint:
|
|
print "Hit breakpoint"
|
|
frame = t.GetFrameAtIndex(0)
|
|
if frame:
|
|
if frame.line_entry:
|
|
print "Stopped at %s:%d" % (frame.line_entry.file.basename, frame.line_entry.line)
|
|
if frame.function:
|
|
print "Stopped in %s" % (frame.function.name,)
|
|
var = frame.FindVariable('intvar')
|
|
if var:
|
|
print "intvar = %s" % (var.GetValue(),)
|
|
else:
|
|
print "no intvar"
|
|
else:
|
|
print "Process state", state
|
|
process.Destroy()
|
|
else:
|
|
print "Failed to create target a.exe"
|
|
|
|
lldb.SBDebugger.Destroy(debugger)
|
|
sys.exit()
|
|
`
|
|
|
|
const expectedLldbOutput = `Created target
|
|
Created breakpoint
|
|
Process launched
|
|
Hit breakpoint
|
|
Stopped at main.go:10
|
|
Stopped in main.main
|
|
intvar = 42
|
|
`
|
|
|
|
func TestLldbPython(t *testing.T) {
|
|
testenv.MustHaveGoBuild(t)
|
|
if final := os.Getenv("GOROOT_FINAL"); final != "" && runtime.GOROOT() != final {
|
|
t.Skip("gdb test can fail with GOROOT_FINAL pending")
|
|
}
|
|
|
|
checkLldbPython(t)
|
|
|
|
dir, err := ioutil.TempDir("", "go-build")
|
|
if err != nil {
|
|
t.Fatalf("failed to create temp directory: %v", err)
|
|
}
|
|
defer os.RemoveAll(dir)
|
|
|
|
src := filepath.Join(dir, "main.go")
|
|
err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
|
|
if err != nil {
|
|
t.Fatalf("failed to create file: %v", err)
|
|
}
|
|
|
|
cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-N -l", "-o", "a.exe")
|
|
cmd.Dir = dir
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("building source %v\n%s", err, out)
|
|
}
|
|
|
|
src = filepath.Join(dir, "script.py")
|
|
err = ioutil.WriteFile(src, []byte(lldbScriptSource), 0755)
|
|
if err != nil {
|
|
t.Fatalf("failed to create script: %v", err)
|
|
}
|
|
|
|
cmd = exec.Command("/usr/bin/python2.7", "script.py", lldbPath)
|
|
cmd.Dir = dir
|
|
got, _ := cmd.CombinedOutput()
|
|
|
|
if string(got) != expectedLldbOutput {
|
|
if strings.Contains(string(got), "Timeout launching") {
|
|
t.Skip("Timeout launching")
|
|
}
|
|
t.Fatalf("Unexpected lldb output:\n%s", got)
|
|
}
|
|
}
|
|
|
|
// Check that aranges are valid even when lldb isn't installed.
|
|
func TestDwarfAranges(t *testing.T) {
|
|
testenv.MustHaveGoBuild(t)
|
|
dir, err := ioutil.TempDir("", "go-build")
|
|
if err != nil {
|
|
t.Fatalf("failed to create temp directory: %v", err)
|
|
}
|
|
defer os.RemoveAll(dir)
|
|
|
|
src := filepath.Join(dir, "main.go")
|
|
err = ioutil.WriteFile(src, []byte(lldbHelloSource), 0644)
|
|
if err != nil {
|
|
t.Fatalf("failed to create file: %v", err)
|
|
}
|
|
|
|
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
|
|
cmd.Dir = dir
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("building source %v\n%s", err, out)
|
|
}
|
|
|
|
filename := filepath.Join(dir, "a.exe")
|
|
if f, err := elf.Open(filename); err == nil {
|
|
sect := f.Section(".debug_aranges")
|
|
if sect == nil {
|
|
t.Fatal("Missing aranges section")
|
|
}
|
|
verifyAranges(t, f.ByteOrder, sect.Open())
|
|
} else if f, err := macho.Open(filename); err == nil {
|
|
sect := f.Section("__debug_aranges")
|
|
if sect == nil {
|
|
t.Fatal("Missing aranges section")
|
|
}
|
|
verifyAranges(t, f.ByteOrder, sect.Open())
|
|
} else {
|
|
t.Skip("Not an elf or macho binary.")
|
|
}
|
|
}
|
|
|
|
func verifyAranges(t *testing.T, byteorder binary.ByteOrder, data io.ReadSeeker) {
|
|
var header struct {
|
|
UnitLength uint32 // does not include the UnitLength field
|
|
Version uint16
|
|
Offset uint32
|
|
AddressSize uint8
|
|
SegmentSize uint8
|
|
}
|
|
for {
|
|
offset, err := data.Seek(0, io.SeekCurrent)
|
|
if err != nil {
|
|
t.Fatalf("Seek error: %v", err)
|
|
}
|
|
if err = binary.Read(data, byteorder, &header); err == io.EOF {
|
|
return
|
|
} else if err != nil {
|
|
t.Fatalf("Error reading arange header: %v", err)
|
|
}
|
|
tupleSize := int64(header.SegmentSize) + 2*int64(header.AddressSize)
|
|
lastTupleOffset := offset + int64(header.UnitLength) + 4 - tupleSize
|
|
if lastTupleOffset%tupleSize != 0 {
|
|
t.Fatalf("Invalid arange length %d, (addr %d, seg %d)", header.UnitLength, header.AddressSize, header.SegmentSize)
|
|
}
|
|
if _, err = data.Seek(lastTupleOffset, io.SeekStart); err != nil {
|
|
t.Fatalf("Seek error: %v", err)
|
|
}
|
|
buf := make([]byte, tupleSize)
|
|
if n, err := data.Read(buf); err != nil || int64(n) < tupleSize {
|
|
t.Fatalf("Read error: %v", err)
|
|
}
|
|
for _, val := range buf {
|
|
if val != 0 {
|
|
t.Fatalf("Invalid terminator")
|
|
}
|
|
}
|
|
}
|
|
}
|