github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/compile/internal/ssa/stmtlines_test.go (about)

     1  package ssa_test
     2  
     3  import (
     4  	"debug/dwarf"
     5  	"debug/elf"
     6  	"debug/macho"
     7  	"debug/pe"
     8  	"fmt"
     9  	"internal/testenv"
    10  	"io"
    11  	"runtime"
    12  	"testing"
    13  )
    14  
    15  func open(path string) (*dwarf.Data, error) {
    16  	if fh, err := elf.Open(path); err == nil {
    17  		return fh.DWARF()
    18  	}
    19  
    20  	if fh, err := pe.Open(path); err == nil {
    21  		return fh.DWARF()
    22  	}
    23  
    24  	if fh, err := macho.Open(path); err == nil {
    25  		return fh.DWARF()
    26  	}
    27  
    28  	return nil, fmt.Errorf("unrecognized executable format")
    29  }
    30  
    31  func must(err error) {
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  }
    36  
    37  type Line struct {
    38  	File string
    39  	Line int
    40  }
    41  
    42  func TestStmtLines(t *testing.T) {
    43  	if runtime.GOOS == "plan9" {
    44  		t.Skip("skipping on plan9; no DWARF symbol table in executables")
    45  	}
    46  
    47  	lines := map[Line]bool{}
    48  	dw, err := open(testenv.GoToolPath(t))
    49  	must(err)
    50  	rdr := dw.Reader()
    51  	rdr.Seek(0)
    52  	for {
    53  		e, err := rdr.Next()
    54  		must(err)
    55  		if e == nil {
    56  			break
    57  		}
    58  		if e.Tag != dwarf.TagCompileUnit {
    59  			continue
    60  		}
    61  		pkgname, _ := e.Val(dwarf.AttrName).(string)
    62  		if pkgname == "runtime" {
    63  			continue
    64  		}
    65  		if e.Val(dwarf.AttrStmtList) == nil {
    66  			continue
    67  		}
    68  		lrdr, err := dw.LineReader(e)
    69  		must(err)
    70  
    71  		var le dwarf.LineEntry
    72  
    73  		for {
    74  			err := lrdr.Next(&le)
    75  			if err == io.EOF {
    76  				break
    77  			}
    78  			must(err)
    79  			fl := Line{le.File.Name, le.Line}
    80  			lines[fl] = lines[fl] || le.IsStmt
    81  		}
    82  	}
    83  
    84  	nonStmtLines := []Line{}
    85  	for line, isstmt := range lines {
    86  		if !isstmt {
    87  			nonStmtLines = append(nonStmtLines, line)
    88  		}
    89  	}
    90  
    91  	if runtime.GOARCH == "amd64" && len(nonStmtLines)*100 > len(lines) { // > 99% obtained on amd64, no backsliding
    92  		t.Errorf("Saw too many (amd64, > 1%%) lines without statement marks, total=%d, nostmt=%d\n", len(lines), len(nonStmtLines))
    93  	}
    94  	if len(nonStmtLines)*100 > 2*len(lines) { // expect 98% elsewhere.
    95  		t.Errorf("Saw too many (not amd64, > 2%%) lines without statement marks, total=%d, nostmt=%d\n", len(lines), len(nonStmtLines))
    96  	}
    97  	t.Logf("total=%d, nostmt=%d\n", len(lines), len(nonStmtLines))
    98  }