proc/native: support watchpoints on Windows (#2651)
This commit is contained in:
parent
2b306e32a6
commit
b50052cc17
@ -25,7 +25,6 @@ Tests skipped by each supported backend:
|
||||
* 2 upstream issue - https://github.com/golang/go/issues/29322
|
||||
* rr skipped = 3
|
||||
* 3 not implemented
|
||||
* windows skipped = 5
|
||||
* windows skipped = 2
|
||||
* 1 broken
|
||||
* 3 not implemented
|
||||
* 1 upstream issue
|
||||
|
||||
39
pkg/proc/native/hwbreak_amd64.go
Normal file
39
pkg/proc/native/hwbreak_amd64.go
Normal file
@ -0,0 +1,39 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
)
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
return drs.SetBreakpoint(idx, addr, wtype.Read(), wtype.Write(), wtype.Size())
|
||||
})
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
drs.ClearBreakpoint(idx)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
var retbp *proc.Breakpoint
|
||||
err := t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
ok, idx := drs.GetActiveBreakpoint()
|
||||
if ok {
|
||||
for _, bp := range t.dbp.Breakpoints().M {
|
||||
if bp.WatchType != 0 && bp.HWBreakIndex == idx {
|
||||
retbp = bp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return retbp, nil
|
||||
}
|
||||
21
pkg/proc/native/hwbreak_other.go
Normal file
21
pkg/proc/native/hwbreak_other.go
Normal file
@ -0,0 +1,21 @@
|
||||
// +build !amd64
|
||||
|
||||
package native
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
)
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, errors.New("hardware breakpoints not supported")
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return errors.New("hardware breakpoints not supported")
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return errors.New("hardware breakpoints not supported")
|
||||
}
|
||||
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
"github.com/go-delve/delve/pkg/proc/internal/ebpf"
|
||||
)
|
||||
|
||||
@ -130,16 +131,8 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error {
|
||||
panic(ErrNativeBackendDisabled)
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
panic(ErrNativeBackendDisabled)
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
panic(ErrNativeBackendDisabled)
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
panic(ErrNativeBackendDisabled)
|
||||
func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) error) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
// Stopped returns whether the thread is stopped at
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
sys "golang.org/x/sys/unix"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
)
|
||||
|
||||
// waitStatus is a synonym for the platform-specific WaitStatus
|
||||
@ -133,14 +134,6 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) error) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
sys "golang.org/x/sys/unix"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
)
|
||||
|
||||
type waitStatus sys.WaitStatus
|
||||
@ -121,14 +122,6 @@ func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) error) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -8,15 +8,3 @@ import (
|
||||
func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
|
||||
return fmt.Errorf("restore regs not supported on i386")
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -86,36 +86,3 @@ func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) erro
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
return drs.SetBreakpoint(idx, addr, wtype.Read(), wtype.Write(), wtype.Size())
|
||||
})
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
drs.ClearBreakpoint(idx)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
var retbp *proc.Breakpoint
|
||||
err := t.withDebugRegisters(func(drs *amd64util.DebugRegisters) error {
|
||||
ok, idx := drs.GetActiveBreakpoint()
|
||||
if ok {
|
||||
for _, bp := range t.dbp.Breakpoints().M {
|
||||
if bp.WatchType != 0 && bp.HWBreakIndex == idx {
|
||||
retbp = bp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return retbp, nil
|
||||
}
|
||||
|
||||
@ -42,15 +42,3 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
|
||||
}
|
||||
return restoreRegistersErr
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
sys "golang.org/x/sys/windows"
|
||||
|
||||
"github.com/go-delve/delve/pkg/proc"
|
||||
"github.com/go-delve/delve/pkg/proc/amd64util"
|
||||
"github.com/go-delve/delve/pkg/proc/winutil"
|
||||
)
|
||||
|
||||
@ -157,14 +158,25 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
|
||||
return _SetThreadContext(t.os.hThread, savedRegs.(*winutil.AMD64Registers).Context)
|
||||
}
|
||||
|
||||
func (t *nativeThread) writeHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) error) error {
|
||||
context := winutil.NewCONTEXT()
|
||||
context.ContextFlags = _CONTEXT_DEBUG_REGISTERS
|
||||
|
||||
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error {
|
||||
return proc.ErrHWBreakUnsupported
|
||||
}
|
||||
err := _GetThreadContext(t.os.hThread, context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) {
|
||||
return nil, nil
|
||||
drs := amd64util.NewDebugRegisters(&context.Dr0, &context.Dr1, &context.Dr2, &context.Dr3, &context.Dr6, &context.Dr7)
|
||||
|
||||
err = f(drs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if drs.Dirty {
|
||||
return _SetThreadContext(t.os.hThread, context)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -5332,7 +5332,6 @@ func TestVariablesWithExternalLinking(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWatchpointsBasic(t *testing.T) {
|
||||
skipOn(t, "not implemented", "windows")
|
||||
skipOn(t, "not implemented", "freebsd")
|
||||
skipOn(t, "not implemented", "darwin")
|
||||
skipOn(t, "not implemented", "386")
|
||||
@ -5378,7 +5377,6 @@ func TestWatchpointsBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWatchpointCounts(t *testing.T) {
|
||||
skipOn(t, "not implemented", "windows")
|
||||
skipOn(t, "not implemented", "freebsd")
|
||||
skipOn(t, "not implemented", "darwin")
|
||||
skipOn(t, "not implemented", "386")
|
||||
@ -5496,7 +5494,6 @@ func TestDwrapStartLocation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWatchpointStack(t *testing.T) {
|
||||
skipOn(t, "not implemented", "windows")
|
||||
skipOn(t, "not implemented", "freebsd")
|
||||
skipOn(t, "not implemented", "darwin")
|
||||
skipOn(t, "not implemented", "386")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user