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