Repository: go-delve/delve
Pull request #3269 (2023-02-10 21:41:40)

pkg/proc,service/test: refactor to use strings.ReplaceAll
Use [strings.ReplaceAll](https://pkg.go.dev/strings#ReplaceAll) instead of `strings.Replace` with `-1` as the last argument.

`strings.ReplaceAll` available since go 1.12. But the code already has `ReplaceAll` occurrences in `pkg/dwarf/line/line_parser.go`, `pkg/proc/native/proc_linux.go`, `pkg/terminal/colorize/colorize_test.go`. So, delve supports go version >= 1.12 and PR changes won't break anything.


Patch:
diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md
index bb3224d5..8d49e9df 100644
--- a/Documentation/cli/README.md
+++ b/Documentation/cli/README.md
@@ -699,8 +699,9 @@ Set watchpoint.
 The memory location is specified with the same expression language used by 'print', for example:
 
 	watch v
+	watch -w *(*int)(0x1400007c018)
 
-will watch the address of variable 'v'.
+will watch the address of variable 'v' and writes to an int at addr '0x1400007c018'.
 
 Note that writes that do not change the value of the watched memory address might not be reported.
 
diff --git a/pkg/dwarf/regnum/arm64.go b/pkg/dwarf/regnum/arm64.go
index 3f7805b9..80aff3f2 100644
--- a/pkg/dwarf/regnum/arm64.go
+++ b/pkg/dwarf/regnum/arm64.go
@@ -5,9 +5,9 @@ import (
 )
 
 // The mapping between hardware registers and DWARF registers is specified
-// in the DWARF for the ARM® Architecture page 7,
-// Table 1
-// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf
+// in the DWARF for the DWARF for the Arm® 64-bit Architecture (AArch64),
+// Section 4, Table 1
+// https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst#4arm-specific-dwarf-definitions
 
 const (
 	ARM64_X0         = 0  // X1 through X30 follow
diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go
index 3ad16ebe..dd92fe58 100644
--- a/pkg/proc/bininfo.go
+++ b/pkg/proc/bininfo.go
@@ -1899,8 +1899,8 @@ func (bi *BinaryInfo) macOSDebugFrameBugWorkaround() {
 
 // Do not call this function directly it isn't able to deal correctly with package paths
 func (bi *BinaryInfo) findType(name string) (godwarf.Type, error) {
-	name = strings.Replace(name, "interface{", "interface {", -1)
-	name = strings.Replace(name, "struct{", "struct {", -1)
+	name = strings.ReplaceAll(name, "interface{", "interface {")
+	name = strings.ReplaceAll(name, "struct{", "struct {")
 	ref, found := bi.types[name]
 	if !found {
 		return nil, reader.ErrTypeNotFound
@@ -2096,7 +2096,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB
 			}
 			gopkg, _ := entry.Val(godwarf.AttrGoPackageName).(string)
 			if cu.isgo && gopkg != "" {
-				bi.PackageMap[gopkg] = append(bi.PackageMap[gopkg], escapePackagePath(strings.Replace(cu.name, "\\", "/", -1)))
+				bi.PackageMap[gopkg] = append(bi.PackageMap[gopkg], escapePackagePath(strings.ReplaceAll(cu.name, "\\", "/")))
 			}
 			image.compileUnits = append(image.compileUnits, cu)
 			if entry.Children {
@@ -2515,7 +2515,7 @@ func escapePackagePath(pkg string) string {
 	if slash < 0 {
 		slash = 0
 	}
-	return pkg[:slash] + strings.Replace(pkg[slash:], ".", "%2e", -1)
+	return pkg[:slash] + strings.ReplaceAll(pkg[slash:], ".", "%2e")
 }
 
 // Looks up symbol (either functions or global variables) at address addr.
@@ -2566,7 +2566,7 @@ func (bi *BinaryInfo) ListPackagesBuildInfo(includeFiles bool) []*PackageBuildIn
 			continue
 		}
 
-		ip := strings.Replace(cu.name, "\\", "/", -1)
+		ip := strings.ReplaceAll(cu.name, "\\", "/")
 		if _, ok := m[ip]; !ok {
 			path := cu.lineInfo.FirstFile()
 			if ext := filepath.Ext(path); ext != ".go" && ext != ".s" {
diff --git a/pkg/proc/native/proc_freebsd.go b/pkg/proc/native/proc_freebsd.go
index be659065..44fbc6b6 100644
--- a/pkg/proc/native/proc_freebsd.go
+++ b/pkg/proc/native/proc_freebsd.go
@@ -146,7 +146,7 @@ func initialize(dbp *nativeProcess) error {
 	comm, _ := C.find_command_name(C.int(dbp.pid))
 	defer C.free(unsafe.Pointer(comm))
 	comm_str := C.GoString(comm)
-	dbp.os.comm = strings.Replace(string(comm_str), "%", "%%", -1)
+	dbp.os.comm = strings.ReplaceAll(string(comm_str), "%", "%%")
 	return nil
 }
 
diff --git a/pkg/proc/native/ptrace_freebsd.go b/pkg/proc/native/ptrace_freebsd.go
index 93cc90c2..6ccffe6b 100644
--- a/pkg/proc/native/ptrace_freebsd.go
+++ b/pkg/proc/native/ptrace_freebsd.go
@@ -9,8 +9,9 @@ package native
 import "C"
 
 import (
-	"unsafe"
+	"runtime"
 	"syscall"
+	"unsafe"
 
 	sys "golang.org/x/sys/unix"
 )
@@ -60,11 +61,13 @@ func ptraceGetLwpInfo(wpid int) (info sys.PtraceLwpInfoStruct, err error) {
 
 // id may be a PID or an LWPID
 func ptraceReadData(id int, addr uintptr, data []byte) (n int, err error) {
+	defer runtime.KeepAlive(&data[0]) // PIN
 	return sys.PtraceIO(sys.PIOD_READ_D, id, addr, data, len(data))
 }
 
 // id may be a PID or an LWPID
 func ptraceWriteData(id int, addr uintptr, data []byte) (n int, err error) {
+	defer runtime.KeepAlive(&data[0]) // PIN
 	return sys.PtraceIO(sys.PIOD_WRITE_D, id, addr, data, len(data))
 }
 
diff --git a/pkg/proc/native/ptrace_linux_386.go b/pkg/proc/native/ptrace_linux_386.go
index 82e97878..3139e3d3 100644
--- a/pkg/proc/native/ptrace_linux_386.go
+++ b/pkg/proc/native/ptrace_linux_386.go
@@ -69,9 +69,7 @@ func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
 	len_iov := uint32(len(data))
 	local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
 	remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
-	p_local := uintptr(unsafe.Pointer(&local_iov))
-	p_remote := uintptr(unsafe.Pointer(&remote_iov))
-	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), p_local, 1, p_remote, 1, 0)
+	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
 	if err != syscall.Errno(0) {
 		return 0, err
 	}
@@ -83,9 +81,7 @@ func processVmWrite(tid int, addr uintptr, data []byte) (int, error) {
 	len_iov := uint32(len(data))
 	local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
 	remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
-	p_local := uintptr(unsafe.Pointer(&local_iov))
-	p_remote := uintptr(unsafe.Pointer(&remote_iov))
-	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), p_local, 1, p_remote, 1, 0)
+	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
 	if err != syscall.Errno(0) {
 		return 0, err
 	}
diff --git a/pkg/proc/native/ptrace_linux_64bit.go b/pkg/proc/native/ptrace_linux_64bit.go
index f4ab69c8..542645bd 100644
--- a/pkg/proc/native/ptrace_linux_64bit.go
+++ b/pkg/proc/native/ptrace_linux_64bit.go
@@ -15,9 +15,7 @@ func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
 	len_iov := uint64(len(data))
 	local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
 	remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
-	p_local := uintptr(unsafe.Pointer(&local_iov))
-	p_remote := uintptr(unsafe.Pointer(&remote_iov))
-	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), p_local, 1, p_remote, 1, 0)
+	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
 	if err != syscall.Errno(0) {
 		return 0, err
 	}
@@ -29,9 +27,7 @@ func processVmWrite(tid int, addr uintptr, data []byte) (int, error) {
 	len_iov := uint64(len(data))
 	local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
 	remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
-	p_local := uintptr(unsafe.Pointer(&local_iov))
-	p_remote := uintptr(unsafe.Pointer(&remote_iov))
-	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), p_local, 1, p_remote, 1, 0)
+	n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
 	if err != syscall.Errno(0) {
 		return 0, err
 	}
diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go
index c3f802ac..3553e78e 100644
--- a/pkg/terminal/command.go
+++ b/pkg/terminal/command.go
@@ -144,8 +144,9 @@ See also: "help on", "help cond" and "help clear"`},
 The memory location is specified with the same expression language used by 'print', for example:
 
 	watch v
+	watch -w *(*int)(0x1400007c018)
 
-will watch the address of variable 'v'.
+will watch the address of variable 'v' and writes to an int at addr '0x1400007c018'.
 
 Note that writes that do not change the value of the watched memory address might not be reported.
 


Test patch:
diff --git a/_scripts/test_linux.sh b/_scripts/test_linux.sh
index 4b18efc2..44ca5d7b 100755
--- a/_scripts/test_linux.sh
+++ b/_scripts/test_linux.sh
@@ -44,7 +44,7 @@ GOPATH=$(pwd)/go
 export GOPATH
 export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
 go version
-go install honnef.co/go/tools/cmd/staticcheck@2022.1.2 || true
+go install honnef.co/go/tools/cmd/staticcheck@2023.1 || true
 
 uname -a
 echo "$PATH"
diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go
index 5b01a51b..e1c30065 100644
--- a/cmd/dlv/dlv_test.go
+++ b/cmd/dlv/dlv_test.go
@@ -1311,10 +1311,6 @@ func TestStaticcheck(t *testing.T) {
 	if err != nil {
 		t.Skip("staticcheck not installed")
 	}
-	if goversion.VersionAfterOrEqual(runtime.Version(), 1, 20) {
-		//TODO(aarzilli): remove this when there is a version of staticcheck that can support go1.20
-		t.Skip("staticcheck does not support go1.20 currently")
-	}
 	// default checks minus SA1019 which complains about deprecated identifiers, which change between versions of Go.
 	args := []string{"-tests=false", "-checks=all,-SA1019,-ST1000,-ST1003,-ST1016,-S1021,-ST1023", "github.com/go-delve/delve/..."}
 	// * SA1019 is disabled because new deprecations get added on every version
diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go
index 5ee67eee..adb3635a 100644
--- a/pkg/proc/proc_test.go
+++ b/pkg/proc/proc_test.go
@@ -4795,7 +4795,7 @@ func TestListPackagesBuildInfo(t *testing.T) {
 			if fidx < 0 {
 				continue
 			}
-			if !strings.HasSuffix(strings.Replace(pkg.DirectoryPath, "\\", "/", -1), pkg.ImportPath[fidx:]) {
+			if !strings.HasSuffix(strings.ReplaceAll(pkg.DirectoryPath, "\\", "/"), pkg.ImportPath[fidx:]) {
 				t.Errorf("unexpected suffix: %q %q", pkg.ImportPath, pkg.DirectoryPath)
 			}
 		}
@@ -5872,7 +5872,7 @@ func TestNilPtrDerefInBreakInstr(t *testing.T) {
 
 	withTestProcess("asmnilptr/", t, func(p *proc.Target, fixture protest.Fixture) {
 		f := filepath.Join(fixture.BuildDir, asmfile)
-		f = strings.Replace(f, "\\", "/", -1)
+		f = strings.ReplaceAll(f, "\\", "/")
 		setFileBreakpoint(p, t, f, 5)
 		t.Logf("first continue")
 		assertNoError(p.Continue(), t, "Continue()")
diff --git a/pkg/proc/scope_test.go b/pkg/proc/scope_test.go
index a477281e..80031690 100644
--- a/pkg/proc/scope_test.go
+++ b/pkg/proc/scope_test.go
@@ -293,7 +293,7 @@ func (varCheck *varCheck) checkInScope(line int, scope *proc.EvalScope, t *testi
 
 func (varCheck *varCheck) check(line int, v *proc.Variable, t *testing.T, ctxt string) {
 	typ := v.DwarfType.String()
-	typ = strings.Replace(typ, " ", "", -1)
+	typ = strings.ReplaceAll(typ, " ", "")
 	if typ != varCheck.typ {
 		t.Errorf("%d: wrong type for %s (%s), got %s, expected %s", line, v.Name, ctxt, typ, varCheck.typ)
 	}
diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go
index a9261e1a..d58c9338 100644
--- a/pkg/proc/test/support.go
+++ b/pkg/proc/test/support.go
@@ -195,7 +195,7 @@ func BuildFixture(name string, flags BuildFlags) Fixture {
 	source = filepath.ToSlash(source)
 	sympath, err := filepath.EvalSymlinks(source)
 	if err == nil {
-		source = strings.Replace(sympath, "\\", "/", -1)
+		source = strings.ReplaceAll(sympath, "\\", "/")
 	}
 
 	absdir, _ := filepath.Abs(dir)
diff --git a/service/test/common_test.go b/service/test/common_test.go
index 473e3cc6..ef6338e0 100644
--- a/service/test/common_test.go
+++ b/service/test/common_test.go
@@ -56,7 +56,7 @@ func testProgPath(t *testing.T, name string) string {
 	}
 	sympath, err := filepath.EvalSymlinks(fp)
 	if err == nil {
-		fp = strings.Replace(sympath, "\\", "/", -1)
+		fp = strings.ReplaceAll(sympath, "\\", "/")
 	}
 	return fp
 }