cmd/addr2line: don't assume that GOROOT_FINAL is clean

Fixes #41447

Change-Id: I4460c1c7962d02c41622a5ea1a3c4bc3714a1873
Reviewed-on: https://go-review.googlesource.com/c/go/+/255477
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
index 578d88e..7973aa2 100644
--- a/src/cmd/addr2line/addr2line_test.go
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -73,29 +73,37 @@
 	if err != nil {
 		t.Fatalf("Stat failed: %v", err)
 	}
+
 	// Debug paths are stored slash-separated, so convert to system-native.
 	srcPath = filepath.FromSlash(srcPath)
 	fi2, err := os.Stat(srcPath)
-	if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" && strings.HasPrefix(srcPath, gorootFinal) {
-		if os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2)) {
-			// srcPath has had GOROOT_FINAL substituted for GOROOT, and it doesn't
-			// match the actual file. GOROOT probably hasn't been moved to its final
-			// location yet, so try the original location instead.
+
+	// If GOROOT_FINAL is set and srcPath is not the file we expect, perhaps
+	// srcPath has had GOROOT_FINAL substituted for GOROOT and GOROOT hasn't been
+	// moved to its final location yet. If so, try the original location instead.
+	if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" &&
+		(os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2))) {
+		// srcPath is clean, but GOROOT_FINAL itself might not be.
+		// (See https://golang.org/issue/41447.)
+		gorootFinal = filepath.Clean(gorootFinal)
+
+		if strings.HasPrefix(srcPath, gorootFinal) {
 			fi2, err = os.Stat(runtime.GOROOT() + strings.TrimPrefix(srcPath, gorootFinal))
 		}
 	}
+
 	if err != nil {
 		t.Fatalf("Stat failed: %v", err)
 	}
 	if !os.SameFile(fi1, fi2) {
 		t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
 	}
-	if srcLineNo != "99" {
-		t.Fatalf("line number = %v; want 99", srcLineNo)
+	if srcLineNo != "107" {
+		t.Fatalf("line number = %v; want 107", srcLineNo)
 	}
 }
 
-// This is line 98. The test depends on that.
+// This is line 106. The test depends on that.
 func TestAddr2Line(t *testing.T) {
 	testenv.MustHaveGoBuild(t)