提交 9ee21686 编写于 作者: A aarzilli 提交者: Derek Parker

proc: report errors when loading executable on attach

Fixes #940
上级 f553c95e
...@@ -43,6 +43,9 @@ type BinaryInfo struct { ...@@ -43,6 +43,9 @@ type BinaryInfo struct {
loadModuleDataOnce sync.Once loadModuleDataOnce sync.Once
moduleData []moduleData moduleData []moduleData
nameOfRuntimeType map[uintptr]nameOfRuntimeTypeEntry nameOfRuntimeType map[uintptr]nameOfRuntimeTypeEntry
loadErrMu sync.Mutex
loadErr error
} }
var UnsupportedLinuxArchErr = errors.New("unsupported architecture - only linux/amd64 is supported") var UnsupportedLinuxArchErr = errors.New("unsupported architecture - only linux/amd64 is supported")
...@@ -131,6 +134,16 @@ func (bi *BinaryInfo) Close() error { ...@@ -131,6 +134,16 @@ func (bi *BinaryInfo) Close() error {
return bi.closer.Close() return bi.closer.Close()
} }
func (bi *BinaryInfo) setLoadError(fmtstr string, args ...interface{}) {
bi.loadErrMu.Lock()
bi.loadErr = fmt.Errorf(fmtstr, args...)
bi.loadErrMu.Unlock()
}
func (bi *BinaryInfo) LoadError() error {
return bi.loadErr
}
// ELF /////////////////////////////////////////////////////////////// // ELF ///////////////////////////////////////////////////////////////
func (bi *BinaryInfo) LoadBinaryInfoElf(path string, wg *sync.WaitGroup) error { func (bi *BinaryInfo) LoadBinaryInfoElf(path string, wg *sync.WaitGroup) error {
...@@ -169,18 +182,18 @@ func (bi *BinaryInfo) parseDebugFrameElf(exe *elf.File, wg *sync.WaitGroup) { ...@@ -169,18 +182,18 @@ func (bi *BinaryInfo) parseDebugFrameElf(exe *elf.File, wg *sync.WaitGroup) {
if debugFrameSec != nil && debugInfoSec != nil { if debugFrameSec != nil && debugInfoSec != nil {
debugFrame, err := exe.Section(".debug_frame").Data() debugFrame, err := exe.Section(".debug_frame").Data()
if err != nil { if err != nil {
fmt.Println("could not get .debug_frame section", err) bi.setLoadError("could not get .debug_frame section: %v", err)
os.Exit(1) return
} }
dat, err := debugInfoSec.Data() dat, err := debugInfoSec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .debug_info section", err) bi.setLoadError("could not get .debug_frame section: %v", err)
os.Exit(1) return
} }
bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat)) bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat))
} else { } else {
fmt.Println("could not find .debug_frame section in binary") bi.setLoadError("could not find .debug_frame section in binary")
os.Exit(1) return
} }
} }
...@@ -196,24 +209,24 @@ func (bi *BinaryInfo) obtainGoSymbolsElf(exe *elf.File, wg *sync.WaitGroup) { ...@@ -196,24 +209,24 @@ func (bi *BinaryInfo) obtainGoSymbolsElf(exe *elf.File, wg *sync.WaitGroup) {
if sec := exe.Section(".gosymtab"); sec != nil { if sec := exe.Section(".gosymtab"); sec != nil {
symdat, err = sec.Data() symdat, err = sec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .gosymtab section", err) bi.setLoadError("could not get .gosymtab section: %v", err)
os.Exit(1) return
} }
} }
if sec := exe.Section(".gopclntab"); sec != nil { if sec := exe.Section(".gopclntab"); sec != nil {
pclndat, err = sec.Data() pclndat, err = sec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .gopclntab section", err) bi.setLoadError("could not get .gopclntab section: %v", err)
os.Exit(1) return
} }
} }
pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr) pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr)
tab, err := gosym.NewTable(symdat, pcln) tab, err := gosym.NewTable(symdat, pcln)
if err != nil { if err != nil {
fmt.Println("could not get initialize line table", err) bi.setLoadError("could not get initialize line table: %v", err)
os.Exit(1) return
} }
bi.goSymTable = tab bi.goSymTable = tab
...@@ -225,13 +238,13 @@ func (bi *BinaryInfo) parseDebugLineInfoElf(exe *elf.File, wg *sync.WaitGroup) { ...@@ -225,13 +238,13 @@ func (bi *BinaryInfo) parseDebugLineInfoElf(exe *elf.File, wg *sync.WaitGroup) {
if sec := exe.Section(".debug_line"); sec != nil { if sec := exe.Section(".debug_line"); sec != nil {
debugLine, err := exe.Section(".debug_line").Data() debugLine, err := exe.Section(".debug_line").Data()
if err != nil { if err != nil {
fmt.Println("could not get .debug_line section", err) bi.setLoadError("could not get .debug_line section: %v", err)
os.Exit(1) return
} }
bi.lineInfo = line.Parse(debugLine) bi.lineInfo = line.Parse(debugLine)
} else { } else {
fmt.Println("could not find .debug_line section in binary") bi.setLoadError("could not find .debug_line section in binary")
os.Exit(1) return
} }
} }
...@@ -246,8 +259,8 @@ func (bi *BinaryInfo) setGStructOffsetElf(exe *elf.File, wg *sync.WaitGroup) { ...@@ -246,8 +259,8 @@ func (bi *BinaryInfo) setGStructOffsetElf(exe *elf.File, wg *sync.WaitGroup) {
// offset in libc's TLS block. // offset in libc's TLS block.
symbols, err := exe.Symbols() symbols, err := exe.Symbols()
if err != nil { if err != nil {
fmt.Println("could not parse ELF symbols", err) bi.setLoadError("could not parse ELF symbols: %v", err)
os.Exit(1) return
} }
var tlsg *elf.Symbol var tlsg *elf.Symbol
for _, symbol := range symbols { for _, symbol := range symbols {
...@@ -325,41 +338,41 @@ func (bi *BinaryInfo) parseDebugFramePE(exe *pe.File, wg *sync.WaitGroup) { ...@@ -325,41 +338,41 @@ func (bi *BinaryInfo) parseDebugFramePE(exe *pe.File, wg *sync.WaitGroup) {
if debugFrameSec != nil && debugInfoSec != nil { if debugFrameSec != nil && debugInfoSec != nil {
debugFrame, err := debugFrameSec.Data() debugFrame, err := debugFrameSec.Data()
if err != nil && uint32(len(debugFrame)) < debugFrameSec.Size { if err != nil && uint32(len(debugFrame)) < debugFrameSec.Size {
fmt.Println("could not get .debug_frame section", err) bi.setLoadError("could not get .debug_frame section: %v", err)
os.Exit(1) return
} }
if 0 < debugFrameSec.VirtualSize && debugFrameSec.VirtualSize < debugFrameSec.Size { if 0 < debugFrameSec.VirtualSize && debugFrameSec.VirtualSize < debugFrameSec.Size {
debugFrame = debugFrame[:debugFrameSec.VirtualSize] debugFrame = debugFrame[:debugFrameSec.VirtualSize]
} }
dat, err := debugInfoSec.Data() dat, err := debugInfoSec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .debug_info section", err) bi.setLoadError("could not get .debug_info section: %v", err)
os.Exit(1) return
} }
bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat)) bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat))
} else { } else {
fmt.Println("could not find .debug_frame section in binary") bi.setLoadError("could not find .debug_frame section in binary")
os.Exit(1) return
} }
} }
func (dbp *BinaryInfo) obtainGoSymbolsPE(exe *pe.File, wg *sync.WaitGroup) { func (bi *BinaryInfo) obtainGoSymbolsPE(exe *pe.File, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
_, symdat, pclndat, err := pclnPE(exe) _, symdat, pclndat, err := pclnPE(exe)
if err != nil { if err != nil {
fmt.Println("could not get Go symbols", err) bi.setLoadError("could not get Go symbols: %v", err)
os.Exit(1) return
} }
pcln := gosym.NewLineTable(pclndat, uint64(exe.Section(".text").Offset)) pcln := gosym.NewLineTable(pclndat, uint64(exe.Section(".text").Offset))
tab, err := gosym.NewTable(symdat, pcln) tab, err := gosym.NewTable(symdat, pcln)
if err != nil { if err != nil {
fmt.Println("could not get initialize line table", err) bi.setLoadError("could not get initialize line table: %v", err)
os.Exit(1) return
} }
dbp.goSymTable = tab bi.goSymTable = tab
} }
// Borrowed from https://golang.org/src/cmd/internal/objfile/pe.go // Borrowed from https://golang.org/src/cmd/internal/objfile/pe.go
...@@ -438,16 +451,16 @@ func (bi *BinaryInfo) parseDebugLineInfoPE(exe *pe.File, wg *sync.WaitGroup) { ...@@ -438,16 +451,16 @@ func (bi *BinaryInfo) parseDebugLineInfoPE(exe *pe.File, wg *sync.WaitGroup) {
if sec := exe.Section(".debug_line"); sec != nil { if sec := exe.Section(".debug_line"); sec != nil {
debugLine, err := sec.Data() debugLine, err := sec.Data()
if err != nil && uint32(len(debugLine)) < sec.Size { if err != nil && uint32(len(debugLine)) < sec.Size {
fmt.Println("could not get .debug_line section", err) bi.setLoadError("could not get .debug_line section: %v", err)
os.Exit(1) return
} }
if 0 < sec.VirtualSize && sec.VirtualSize < sec.Size { if 0 < sec.VirtualSize && sec.VirtualSize < sec.Size {
debugLine = debugLine[:sec.VirtualSize] debugLine = debugLine[:sec.VirtualSize]
} }
bi.lineInfo = line.Parse(debugLine) bi.lineInfo = line.Parse(debugLine)
} else { } else {
fmt.Println("could not find .debug_line section in binary") bi.setLoadError("could not find .debug_line section in binary")
os.Exit(1) return
} }
} }
...@@ -485,18 +498,18 @@ func (bi *BinaryInfo) parseDebugFrameMacho(exe *macho.File, wg *sync.WaitGroup) ...@@ -485,18 +498,18 @@ func (bi *BinaryInfo) parseDebugFrameMacho(exe *macho.File, wg *sync.WaitGroup)
if debugFrameSec != nil && debugInfoSec != nil { if debugFrameSec != nil && debugInfoSec != nil {
debugFrame, err := exe.Section("__debug_frame").Data() debugFrame, err := exe.Section("__debug_frame").Data()
if err != nil { if err != nil {
fmt.Println("could not get __debug_frame section", err) bi.setLoadError("could not get __debug_frame section: %v", err)
os.Exit(1) return
} }
dat, err := debugInfoSec.Data() dat, err := debugInfoSec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .debug_info section", err) bi.setLoadError("could not get .debug_info section: %v", err)
os.Exit(1) return
} }
bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat)) bi.frameEntries = frame.Parse(debugFrame, frame.DwarfEndian(dat))
} else { } else {
fmt.Println("could not find __debug_frame section in binary") bi.setLoadError("could not find __debug_frame section in binary")
os.Exit(1) return
} }
} }
...@@ -512,24 +525,24 @@ func (bi *BinaryInfo) obtainGoSymbolsMacho(exe *macho.File, wg *sync.WaitGroup) ...@@ -512,24 +525,24 @@ func (bi *BinaryInfo) obtainGoSymbolsMacho(exe *macho.File, wg *sync.WaitGroup)
if sec := exe.Section("__gosymtab"); sec != nil { if sec := exe.Section("__gosymtab"); sec != nil {
symdat, err = sec.Data() symdat, err = sec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .gosymtab section", err) bi.setLoadError("could not get .gosymtab section: %v", err)
os.Exit(1) return
} }
} }
if sec := exe.Section("__gopclntab"); sec != nil { if sec := exe.Section("__gopclntab"); sec != nil {
pclndat, err = sec.Data() pclndat, err = sec.Data()
if err != nil { if err != nil {
fmt.Println("could not get .gopclntab section", err) bi.setLoadError("could not get .gopclntab section: %v", err)
os.Exit(1) return
} }
} }
pcln := gosym.NewLineTable(pclndat, exe.Section("__text").Addr) pcln := gosym.NewLineTable(pclndat, exe.Section("__text").Addr)
tab, err := gosym.NewTable(symdat, pcln) tab, err := gosym.NewTable(symdat, pcln)
if err != nil { if err != nil {
fmt.Println("could not get initialize line table", err) bi.setLoadError("could not get initialize line table: %v", err)
os.Exit(1) return
} }
bi.goSymTable = tab bi.goSymTable = tab
...@@ -541,12 +554,12 @@ func (bi *BinaryInfo) parseDebugLineInfoMacho(exe *macho.File, wg *sync.WaitGrou ...@@ -541,12 +554,12 @@ func (bi *BinaryInfo) parseDebugLineInfoMacho(exe *macho.File, wg *sync.WaitGrou
if sec := exe.Section("__debug_line"); sec != nil { if sec := exe.Section("__debug_line"); sec != nil {
debugLine, err := exe.Section("__debug_line").Data() debugLine, err := exe.Section("__debug_line").Data()
if err != nil { if err != nil {
fmt.Println("could not get __debug_line section", err) bi.setLoadError("could not get __debug_line section: %v", err)
os.Exit(1) return
} }
bi.lineInfo = line.Parse(debugLine) bi.lineInfo = line.Parse(debugLine)
} else { } else {
fmt.Println("could not find __debug_line section in binary") bi.setLoadError("could not find __debug_line section in binary")
os.Exit(1) return
} }
} }
...@@ -175,8 +175,14 @@ func OpenCore(corePath, exePath string) (*Process, error) { ...@@ -175,8 +175,14 @@ func OpenCore(corePath, exePath string) (*Process, error) {
} }
var wg sync.WaitGroup var wg sync.WaitGroup
p.bi.LoadBinaryInfo(exePath, &wg) err = p.bi.LoadBinaryInfo(exePath, &wg)
wg.Wait() wg.Wait()
if err == nil {
err = p.bi.LoadError()
}
if err != nil {
return nil, err
}
for _, th := range p.core.Threads { for _, th := range p.core.Threads {
p.currentThread = th p.currentThread = th
......
...@@ -132,7 +132,7 @@ func withCoreFile(t *testing.T, name, args string) *Process { ...@@ -132,7 +132,7 @@ func withCoreFile(t *testing.T, name, args string) *Process {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
fix := test.BuildFixture(name) fix := test.BuildFixture(name, 0)
bashCmd := fmt.Sprintf("cd %v && ulimit -c unlimited && GOTRACEBACK=crash %v %s", tempDir, fix.Path, args) bashCmd := fmt.Sprintf("cd %v && ulimit -c unlimited && GOTRACEBACK=crash %v %s", tempDir, fix.Path, args)
exec.Command("bash", "-c", bashCmd).Run() exec.Command("bash", "-c", bashCmd).Run()
cores, err := filepath.Glob(path.Join(tempDir, "core*")) cores, err := filepath.Glob(path.Join(tempDir, "core*"))
......
...@@ -263,11 +263,14 @@ func (p *Process) Connect(conn net.Conn, path string, pid int) error { ...@@ -263,11 +263,14 @@ func (p *Process) Connect(conn net.Conn, path string, pid int) error {
var wg sync.WaitGroup var wg sync.WaitGroup
err = p.bi.LoadBinaryInfo(path, &wg) err = p.bi.LoadBinaryInfo(path, &wg)
wg.Wait()
if err == nil {
err = p.bi.LoadError()
}
if err != nil { if err != nil {
conn.Close() conn.Close()
return err return err
} }
wg.Wait()
// None of the stubs we support returns the value of fs_base or gs_base // None of the stubs we support returns the value of fs_base or gs_base
// along with the registers, therefore we have to resort to executing a MOV // along with the registers, therefore we have to resort to executing a MOV
......
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
) )
func withTestRecording(name string, t testing.TB, fn func(p *gdbserial.Process, fixture protest.Fixture)) { func withTestRecording(name string, t testing.TB, fn func(p *gdbserial.Process, fixture protest.Fixture)) {
fixture := protest.BuildFixture(name) fixture := protest.BuildFixture(name, 0)
protest.MustHaveRecordingAllowed(t) protest.MustHaveRecordingAllowed(t)
if path, _ := exec.LookPath("rr"); path == "" { if path, _ := exec.LookPath("rr"); path == "" {
t.Skip("test skipped, rr not found") t.Skip("test skipped, rr not found")
......
...@@ -163,10 +163,13 @@ func (dbp *Process) LoadInformation(path string) error { ...@@ -163,10 +163,13 @@ func (dbp *Process) LoadInformation(path string) error {
wg.Add(1) wg.Add(1)
go dbp.loadProcessInformation(&wg) go dbp.loadProcessInformation(&wg)
dbp.bi.LoadBinaryInfo(path, &wg) err := dbp.bi.LoadBinaryInfo(path, &wg)
wg.Wait() wg.Wait()
if err == nil {
err = dbp.bi.LoadError()
}
return nil return err
} }
// RequestManualStop sets the `halt` flag and // RequestManualStop sets the `halt` flag and
...@@ -388,11 +391,11 @@ func (dbp *Process) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) { ...@@ -388,11 +391,11 @@ func (dbp *Process) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
func initializeDebugProcess(dbp *Process, path string) (*Process, error) { func initializeDebugProcess(dbp *Process, path string) (*Process, error) {
err := dbp.LoadInformation(path) err := dbp.LoadInformation(path)
if err != nil { if err != nil {
return nil, err return dbp, err
} }
if err := dbp.updateThreadList(); err != nil { if err := dbp.updateThreadList(); err != nil {
return nil, err return dbp, err
} }
// selectedGoroutine can not be set correctly by the call to updateThreadList // selectedGoroutine can not be set correctly by the call to updateThreadList
......
...@@ -152,7 +152,12 @@ func Attach(pid int) (*Process, error) { ...@@ -152,7 +152,12 @@ func Attach(pid int) (*Process, error) {
return nil, err return nil, err
} }
return initializeDebugProcess(dbp, "") dbp, err = initializeDebugProcess(dbp, "")
if err != nil {
dbp.Detach(false)
return nil, err
}
return dbp, nil
} }
// Kill kills the process. // Kill kills the process.
......
...@@ -90,7 +90,12 @@ func Attach(pid int) (*Process, error) { ...@@ -90,7 +90,12 @@ func Attach(pid int) (*Process, error) {
return nil, err return nil, err
} }
return initializeDebugProcess(dbp, "") dbp, err = initializeDebugProcess(dbp, "")
if err != nil {
dbp.Detach(false)
return nil, err
}
return dbp, nil
} }
// Kill kills the target process. // Kill kills the target process.
......
...@@ -162,7 +162,12 @@ func Attach(pid int) (*Process, error) { ...@@ -162,7 +162,12 @@ func Attach(pid int) (*Process, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return newDebugProcess(New(pid), exepath) dbp, err := newDebugProcess(New(pid), exepath)
if err != nil {
dbp.Detach(false)
return nil, err
}
return dbp, nil
} }
// Kill kills the process. // Kill kills the process.
......
...@@ -48,7 +48,7 @@ func TestMain(m *testing.M) { ...@@ -48,7 +48,7 @@ func TestMain(m *testing.M) {
} }
func withTestProcess(name string, t testing.TB, fn func(p proc.Process, fixture protest.Fixture)) { func withTestProcess(name string, t testing.TB, fn func(p proc.Process, fixture protest.Fixture)) {
fixture := protest.BuildFixture(name) fixture := protest.BuildFixture(name, 0)
var p proc.Process var p proc.Process
var err error var err error
var tracedir string var tracedir string
...@@ -81,7 +81,7 @@ func withTestProcess(name string, t testing.TB, fn func(p proc.Process, fixture ...@@ -81,7 +81,7 @@ func withTestProcess(name string, t testing.TB, fn func(p proc.Process, fixture
} }
func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p proc.Process, fixture protest.Fixture), args []string) { func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p proc.Process, fixture protest.Fixture), args []string) {
fixture := protest.BuildFixture(name) fixture := protest.BuildFixture(name, 0)
var p proc.Process var p proc.Process
var err error var err error
var tracedir string var tracedir string
...@@ -2794,7 +2794,7 @@ func TestAttachDetach(t *testing.T) { ...@@ -2794,7 +2794,7 @@ func TestAttachDetach(t *testing.T) {
if testBackend == "rr" { if testBackend == "rr" {
return return
} }
fixture := protest.BuildFixture("testnextnethttp") fixture := protest.BuildFixture("testnextnethttp", 0)
cmd := exec.Command(fixture.Path) cmd := exec.Command(fixture.Path)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
...@@ -3085,3 +3085,65 @@ func TestShadowedFlag(t *testing.T) { ...@@ -3085,3 +3085,65 @@ func TestShadowedFlag(t *testing.T) {
} }
}) })
} }
func TestAttachStripped(t *testing.T) {
if testBackend == "lldb" && runtime.GOOS == "linux" {
bs, _ := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope")
if bs == nil || strings.TrimSpace(string(bs)) != "0" {
t.Logf("can not run TestAttachStripped: %v\n", bs)
return
}
}
if testBackend == "rr" {
return
}
if runtime.GOOS == "darwin" {
t.Log("-s does not produce stripped executables on macOS")
return
}
fixture := protest.BuildFixture("testnextnethttp", protest.LinkStrip)
cmd := exec.Command(fixture.Path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
assertNoError(cmd.Start(), t, "starting fixture")
// wait for testnextnethttp to start listening
t0 := time.Now()
for {
conn, err := net.Dial("tcp", "localhost:9191")
if err == nil {
conn.Close()
break
}
time.Sleep(50 * time.Millisecond)
if time.Since(t0) > 10*time.Second {
t.Fatal("fixture did not start")
}
}
var p proc.Process
var err error
switch testBackend {
case "native":
p, err = native.Attach(cmd.Process.Pid)
case "lldb":
path := ""
if runtime.GOOS == "darwin" {
path = fixture.Path
}
p, err = gdbserial.LLDBAttach(cmd.Process.Pid, path)
default:
t.Fatalf("unknown backend %q", testBackend)
}
t.Logf("error is %v", err)
if err == nil {
p.Detach(true)
t.Fatalf("expected error after attach, got nothing")
} else {
cmd.Process.Kill()
}
os.Remove(fixture.Path)
}
...@@ -38,8 +38,14 @@ func FindFixturesDir() string { ...@@ -38,8 +38,14 @@ func FindFixturesDir() string {
return fixturesDir return fixturesDir
} }
func BuildFixture(name string) Fixture { type BuildFlags uint32
if f, ok := Fixtures[name]; ok {
const (
LinkStrip = 1 << iota
)
func BuildFixture(name string, flags BuildFlags) Fixture {
if f, ok := Fixtures[name]; ok && flags == 0 {
return f return f
} }
...@@ -62,6 +68,9 @@ func BuildFixture(name string) Fixture { ...@@ -62,6 +68,9 @@ func BuildFixture(name string) Fixture {
// Work-around for https://github.com/golang/go/issues/13154 // Work-around for https://github.com/golang/go/issues/13154
buildFlags = append(buildFlags, "-ldflags=-linkmode internal") buildFlags = append(buildFlags, "-ldflags=-linkmode internal")
} }
if flags&LinkStrip != 0 {
buildFlags = append(buildFlags, "-ldflags=-s")
}
buildFlags = append(buildFlags, "-gcflags=-N -l", "-o", tmpfile) buildFlags = append(buildFlags, "-gcflags=-N -l", "-o", tmpfile)
if path != "" { if path != "" {
buildFlags = append(buildFlags, name+".go") buildFlags = append(buildFlags, name+".go")
...@@ -80,7 +89,13 @@ func BuildFixture(name string) Fixture { ...@@ -80,7 +89,13 @@ func BuildFixture(name string) Fixture {
source, _ := filepath.Abs(path) source, _ := filepath.Abs(path)
source = filepath.ToSlash(source) source = filepath.ToSlash(source)
Fixtures[name] = Fixture{Name: name, Path: tmpfile, Source: source} fixture := Fixture{Name: name, Path: tmpfile, Source: source}
if flags != 0 {
return fixture
}
Fixtures[name] = fixture
return Fixtures[name] return Fixtures[name]
} }
......
...@@ -104,7 +104,7 @@ func withTestTerminal(name string, t testing.TB, fn func(*FakeTerminal)) { ...@@ -104,7 +104,7 @@ func withTestTerminal(name string, t testing.TB, fn func(*FakeTerminal)) {
defer listener.Close() defer listener.Close()
server := rpccommon.NewServer(&service.Config{ server := rpccommon.NewServer(&service.Config{
Listener: listener, Listener: listener,
ProcessArgs: []string{test.BuildFixture(name).Path}, ProcessArgs: []string{test.BuildFixture(name, 0).Path},
Backend: testBackend, Backend: testBackend,
}, false) }, false)
if err := server.Run(); err != nil { if err := server.Run(); err != nil {
......
...@@ -31,7 +31,7 @@ func withTestClient1(name string, t *testing.T, fn func(c *rpc1.RPCClient)) { ...@@ -31,7 +31,7 @@ func withTestClient1(name string, t *testing.T, fn func(c *rpc1.RPCClient)) {
defer listener.Close() defer listener.Close()
server := rpccommon.NewServer(&service.Config{ server := rpccommon.NewServer(&service.Config{
Listener: listener, Listener: listener,
ProcessArgs: []string{protest.BuildFixture(name).Path}, ProcessArgs: []string{protest.BuildFixture(name, 0).Path},
Backend: testBackend, Backend: testBackend,
}, false) }, false)
if err := server.Run(); err != nil { if err := server.Run(); err != nil {
...@@ -740,7 +740,7 @@ func Test1ClientServer_FullStacktrace(t *testing.T) { ...@@ -740,7 +740,7 @@ func Test1ClientServer_FullStacktrace(t *testing.T) {
if arg.Name != "i" { if arg.Name != "i" {
continue continue
} }
t.Logf("frame %d, variable i is %v\n", i, arg) t.Logf("frame %d, variable i is %v\n", i, arg)
argn, err := strconv.Atoi(arg.Value) argn, err := strconv.Atoi(arg.Value)
if err == nil { if err == nil {
found[argn] = true found[argn] = true
......
...@@ -48,7 +48,7 @@ func withTestClient2(name string, t *testing.T, fn func(c service.Client)) { ...@@ -48,7 +48,7 @@ func withTestClient2(name string, t *testing.T, fn func(c service.Client)) {
defer listener.Close() defer listener.Close()
server := rpccommon.NewServer(&service.Config{ server := rpccommon.NewServer(&service.Config{
Listener: listener, Listener: listener,
ProcessArgs: []string{protest.BuildFixture(name).Path}, ProcessArgs: []string{protest.BuildFixture(name, 0).Path},
Backend: testBackend, Backend: testBackend,
}, false) }, false)
if err := server.Run(); err != nil { if err := server.Run(); err != nil {
......
...@@ -106,7 +106,7 @@ func setVariable(p proc.Process, symbol, value string) error { ...@@ -106,7 +106,7 @@ func setVariable(p proc.Process, symbol, value string) error {
} }
func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) { func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) {
fixture := protest.BuildFixture(name) fixture := protest.BuildFixture(name, 0)
var p proc.Process var p proc.Process
var err error var err error
var tracedir string var tracedir string
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册