// the go toolchain itself.
first = false
})
- lo, hi := useVMMap(t)
+ lo, hi, err := useVMMapWithRetry(t)
+ if err != nil {
+ t.Fatal(err)
+ }
if got, want := begin, lo; got != want {
t.Errorf("got %x, want %x", got, want)
}
}
}
-func useVMMap(t *testing.T) (hi, lo uint64) {
+func useVMMapWithRetry(t *testing.T) (hi, lo uint64, err error) {
+ var retryable bool
+ for {
+ hi, lo, retryable, err = useVMMap(t)
+ if err == nil {
+ return hi, lo, nil
+ }
+ if !retryable {
+ return 0, 0, err
+ }
+ t.Logf("retrying vmmap after error: %v", err)
+ }
+}
+
+func useVMMap(t *testing.T) (hi, lo uint64, retryable bool, err error) {
pid := strconv.Itoa(os.Getpid())
testenv.MustHaveExecPath(t, "vmmap")
cmd := testenv.Command(t, "vmmap", pid)
if ee, ok := cmdErr.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
t.Logf("%v: %v\n%s", cmd, cmdErr, ee.Stderr)
}
+ retryable = bytes.Contains(out, []byte("resource shortage"))
t.Logf("%v: %v", cmd, cmdErr)
+ if retryable {
+ return 0, 0, true, cmdErr
+ }
}
// Always parse the output of vmmap since it may return an error
// code even if it successfully reports the text segment information
// required for this test.
- hi, lo, err := parseVmmap(out)
+ hi, lo, err = parseVmmap(out)
if err != nil {
if cmdErr != nil {
- t.Fatalf("failed to parse vmmap output, vmmap reported an error: %v", err)
+ return 0, 0, false, fmt.Errorf("failed to parse vmmap output, vmmap reported an error: %v", err)
}
t.Logf("vmmap output: %s", out)
- t.Fatalf("failed to parse vmmap output, vmmap did not report an error: %v", err)
+ return 0, 0, false, fmt.Errorf("failed to parse vmmap output, vmmap did not report an error: %v", err)
}
- return hi, lo
+ return hi, lo, false, nil
}
// parseVmmap parses the output of vmmap and calls addMapping for the first r-x TEXT segment in the output.