github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/ssa/stmtlines_test.go (about)

     1  package ssa_test
     2  
     3  import (
     4  	cmddwarf "github.com/gagliardetto/golang-go/cmd/internal/dwarf"
     5  	"debug/dwarf"
     6  	"debug/elf"
     7  	"debug/macho"
     8  	"debug/pe"
     9  	"fmt"
    10  	"github.com/gagliardetto/golang-go/not-internal/testenv"
    11  	"github.com/gagliardetto/golang-go/not-internal/xcoff"
    12  	"io"
    13  	"os"
    14  	"runtime"
    15  	"sort"
    16  	"testing"
    17  )
    18  
    19  func open(path string) (*dwarf.Data, error) {
    20  	if fh, err := elf.Open(path); err == nil {
    21  		return fh.DWARF()
    22  	}
    23  
    24  	if fh, err := pe.Open(path); err == nil {
    25  		return fh.DWARF()
    26  	}
    27  
    28  	if fh, err := macho.Open(path); err == nil {
    29  		return fh.DWARF()
    30  	}
    31  
    32  	if fh, err := xcoff.Open(path); err == nil {
    33  		return fh.DWARF()
    34  	}
    35  
    36  	return nil, fmt.Errorf("unrecognized executable format")
    37  }
    38  
    39  func must(err error) {
    40  	if err != nil {
    41  		panic(err)
    42  	}
    43  }
    44  
    45  type Line struct {
    46  	File string
    47  	Line int
    48  }
    49  
    50  func TestStmtLines(t *testing.T) {
    51  	if runtime.GOOS == "plan9" {
    52  		t.Skip("skipping on plan9; no DWARF symbol table in executables")
    53  	}
    54  
    55  	if runtime.GOOS == "aix" {
    56  		extld := os.Getenv("CC")
    57  		if extld == "" {
    58  			extld = "gcc"
    59  		}
    60  		enabled, err := cmddwarf.IsDWARFEnabledOnAIXLd(extld)
    61  		if err != nil {
    62  			t.Fatal(err)
    63  		}
    64  		if !enabled {
    65  			t.Skip("skipping on aix: no DWARF with ld version < 7.2.2 ")
    66  		}
    67  	}
    68  
    69  	lines := map[Line]bool{}
    70  	dw, err := open(testenv.GoToolPath(t))
    71  	must(err)
    72  	rdr := dw.Reader()
    73  	rdr.Seek(0)
    74  	for {
    75  		e, err := rdr.Next()
    76  		must(err)
    77  		if e == nil {
    78  			break
    79  		}
    80  		if e.Tag != dwarf.TagCompileUnit {
    81  			continue
    82  		}
    83  		pkgname, _ := e.Val(dwarf.AttrName).(string)
    84  		if pkgname == "runtime" {
    85  			continue
    86  		}
    87  		if e.Val(dwarf.AttrStmtList) == nil {
    88  			continue
    89  		}
    90  		lrdr, err := dw.LineReader(e)
    91  		must(err)
    92  
    93  		var le dwarf.LineEntry
    94  
    95  		for {
    96  			err := lrdr.Next(&le)
    97  			if err == io.EOF {
    98  				break
    99  			}
   100  			must(err)
   101  			fl := Line{le.File.Name, le.Line}
   102  			lines[fl] = lines[fl] || le.IsStmt
   103  		}
   104  	}
   105  
   106  	nonStmtLines := []Line{}
   107  	for line, isstmt := range lines {
   108  		if !isstmt {
   109  			nonStmtLines = append(nonStmtLines, line)
   110  		}
   111  	}
   112  
   113  	if runtime.GOARCH == "amd64" {
   114  		if len(nonStmtLines)*100 > len(lines) { // > 99% obtained on amd64, no backsliding
   115  			t.Errorf("Saw too many (amd64, > 1%%) lines without statement marks, total=%d, nostmt=%d ('-run TestStmtLines -v' lists failing lines)\n", len(lines), len(nonStmtLines))
   116  		}
   117  	} else if len(nonStmtLines)*100 > 2*len(lines) { // expect 98% elsewhere.
   118  		t.Errorf("Saw too many (not amd64, > 2%%) lines without statement marks, total=%d, nostmt=%d ('-run TestStmtLines -v' lists failing lines)\n", len(lines), len(nonStmtLines))
   119  	}
   120  	if testing.Verbose() {
   121  		sort.Slice(nonStmtLines, func(i, j int) bool {
   122  			if nonStmtLines[i].File != nonStmtLines[j].File {
   123  				return nonStmtLines[i].File < nonStmtLines[j].File
   124  			}
   125  			return nonStmtLines[i].Line < nonStmtLines[j].Line
   126  		})
   127  		for _, l := range nonStmtLines {
   128  			t.Logf("%s:%d has no DWARF is_stmt mark\n", l.File, l.Line)
   129  		}
   130  	}
   131  	t.Logf("total=%d, nostmt=%d\n", len(lines), len(nonStmtLines))
   132  }