blob: 72f317513042c7724c9273a2540032b109a1c030 [file] [log] [blame]
// Copyright 2009 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 dwarf_test
// Stripped-down, simplified version of ../../gosym/pclntab_test.go
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
. "golang.org/x/debug/ogle/debug/dwarf"
"golang.org/x/debug/ogle/debug/elf"
"golang.org/x/debug/ogle/debug/macho"
)
var (
pclineTempDir string
pclinetestBinary string
)
func dotest(self bool) bool {
// For now, only works on amd64 platforms.
if runtime.GOARCH != "amd64" {
return false
}
// Self test reads test binary; only works on Linux or Mac.
if self {
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
return false
}
}
// Command below expects "sh", so Unix.
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
return false
}
if pclinetestBinary != "" {
return true
}
var err error
pclineTempDir, err = ioutil.TempDir("", "pclinetest")
if err != nil {
panic(err)
}
if strings.Contains(pclineTempDir, " ") {
panic("unexpected space in tempdir")
}
// This command builds pclinetest from ../../gosym/pclinetest.asm;
// the resulting binary looks like it was built from pclinetest.s,
// but we have renamed it to keep it away from the go tool.
pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
command := fmt.Sprintf("go tool 6a -o %s.6 ../../gosym/pclinetest.asm && go tool 6l -H %s -E main -o %s %s.6",
pclinetestBinary, runtime.GOOS, pclinetestBinary, pclinetestBinary)
cmd := exec.Command("sh", "-c", command)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
panic(err)
}
return true
}
func endtest() {
if pclineTempDir != "" {
os.RemoveAll(pclineTempDir)
pclineTempDir = ""
pclinetestBinary = ""
}
}
func getData(file string) (*Data, error) {
switch runtime.GOOS {
case "linux":
f, err := elf.Open(file)
if err != nil {
return nil, err
}
dwarf, err := f.DWARF()
if err != nil {
return nil, err
}
f.Close()
return dwarf, nil
case "darwin":
f, err := macho.Open(file)
if err != nil {
return nil, err
}
dwarf, err := f.DWARF()
if err != nil {
return nil, err
}
f.Close()
return dwarf, nil
}
panic("unimplemented DWARF for GOOS=" + runtime.GOOS)
}
func TestPCToLine(t *testing.T) {
if !dotest(false) {
return
}
defer endtest()
data, err := getData(pclinetestBinary)
if err != nil {
t.Fatal(err)
}
// Test PCToLine.
// TODO: Do much more than this.
pc, err := data.LookupFunction("linefrompc")
if err != nil {
t.Fatal(err)
}
file, line, err := data.PCToLine(pc)
if err != nil {
t.Fatal(err)
}
// We expect <longpath>/pclinetest.asm, line 13.
if !strings.HasSuffix(file, "/pclinetest.asm") {
t.Errorf("got %s; want %s", file, ".../pclinetest.asm")
}
if line != 13 {
t.Errorf("got %d; want %d", line, 13)
}
}