mirror of
https://github.com/golang/go
synced 2024-11-19 11:04:47 -07:00
cmd/link: export specialized variants of runtime._type to debug_info
The reflect package can be used to create new types at runtime, these types will have runtime._type entries describing them but no entry in debug_info (obviously). A debugger that wanted to print the value of variables with such types will have to read the runtime._type directly, however the "specializations" of runtime._type (runtime.slicetype, runtime.maptype, etc) are not exported to debug_info, besides runtime.interfacetype. All those types (i.e. runtime.slicetype, runtime.maptype, etc) should be exported to debug_info so that debuggers don't have to hard-code their description. Fixes #19602 Change-Id: I086d523a4421a4ed964e16bc3c2274319a98b45b Reviewed-on: https://go-review.googlesource.com/38350 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e49627d355
commit
073247f11f
@ -1521,10 +1521,20 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
|
||||
}
|
||||
|
||||
// Needed by the prettyprinter code for interface inspection.
|
||||
defgotype(ctxt, lookupOrDiag(ctxt, "type.runtime._type"))
|
||||
|
||||
defgotype(ctxt, lookupOrDiag(ctxt, "type.runtime.interfacetype"))
|
||||
defgotype(ctxt, lookupOrDiag(ctxt, "type.runtime.itab"))
|
||||
for _, typ := range []string{
|
||||
"type.runtime._type",
|
||||
"type.runtime.arraytype",
|
||||
"type.runtime.chantype",
|
||||
"type.runtime.functype",
|
||||
"type.runtime.maptype",
|
||||
"type.runtime.ptrtype",
|
||||
"type.runtime.slicetype",
|
||||
"type.runtime.structtype",
|
||||
"type.runtime.interfacetype",
|
||||
"type.runtime.itab",
|
||||
"type.runtime.imethod"} {
|
||||
defgotype(ctxt, lookupOrDiag(ctxt, typ))
|
||||
}
|
||||
|
||||
genasmsym(ctxt, defdwsymb)
|
||||
|
||||
|
90
src/cmd/link/internal/ld/dwarf_test.go
Normal file
90
src/cmd/link/internal/ld/dwarf_test.go
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2017 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 ld
|
||||
|
||||
import (
|
||||
objfilepkg "cmd/internal/objfile" // renamed to avoid conflict with objfile function
|
||||
"debug/dwarf"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRuntimeTypeDIEs(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
dir, err := ioutil.TempDir("", "TestRuntimeTypeDIEs")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
f := gobuild(t, dir, `package main; func main() { }`)
|
||||
defer f.Close()
|
||||
|
||||
dwarf, err := f.DWARF()
|
||||
if err != nil {
|
||||
t.Fatalf("error reading DWARF: %v", err)
|
||||
}
|
||||
|
||||
want := map[string]bool{
|
||||
"runtime._type": true,
|
||||
"runtime.arraytype": true,
|
||||
"runtime.chantype": true,
|
||||
"runtime.functype": true,
|
||||
"runtime.maptype": true,
|
||||
"runtime.ptrtype": true,
|
||||
"runtime.slicetype": true,
|
||||
"runtime.structtype": true,
|
||||
"runtime.interfacetype": true,
|
||||
"runtime.itab": true,
|
||||
"runtime.imethod": true,
|
||||
}
|
||||
|
||||
found := findTypes(t, dwarf, want)
|
||||
if len(found) != len(want) {
|
||||
t.Errorf("found %v, want %v", found, want)
|
||||
}
|
||||
}
|
||||
|
||||
func findTypes(t *testing.T, dw *dwarf.Data, want map[string]bool) (found map[string]bool) {
|
||||
found = make(map[string]bool)
|
||||
rdr := dw.Reader()
|
||||
for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
|
||||
if err != nil {
|
||||
t.Fatalf("error reading DWARF: %v", err)
|
||||
}
|
||||
switch entry.Tag {
|
||||
case dwarf.TagTypedef:
|
||||
if name, ok := entry.Val(dwarf.AttrName).(string); ok && want[name] {
|
||||
found[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func gobuild(t *testing.T, dir string, testfile string) *objfilepkg.File {
|
||||
src := filepath.Join(dir, "test.go")
|
||||
dst := filepath.Join(dir, "out")
|
||||
|
||||
if err := ioutil.WriteFile(src, []byte(testfile), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
|
||||
if b, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Logf("build: %s\n", b)
|
||||
t.Fatalf("build error: %v", err)
|
||||
}
|
||||
|
||||
f, err := objfilepkg.Open(dst)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return f
|
||||
}
|
Loading…
Reference in New Issue
Block a user