未验证 提交 b50052cc 编写于 作者: A Alessandro Arzilli 提交者: GitHub

proc/native: support watchpoints on Windows (#2651)

上级 2b306e32
...@@ -25,7 +25,6 @@ Tests skipped by each supported backend: ...@@ -25,7 +25,6 @@ Tests skipped by each supported backend:
* 2 upstream issue - https://github.com/golang/go/issues/29322 * 2 upstream issue - https://github.com/golang/go/issues/29322
* rr skipped = 3 * rr skipped = 3
* 3 not implemented * 3 not implemented
* windows skipped = 5 * windows skipped = 2
* 1 broken * 1 broken
* 3 not implemented
* 1 upstream issue * 1 upstream issue
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
}
// +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 ( ...@@ -9,6 +9,7 @@ import (
"github.com/go-delve/delve/pkg/dwarf/op" "github.com/go-delve/delve/pkg/dwarf/op"
"github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/amd64util"
"github.com/go-delve/delve/pkg/proc/internal/ebpf" "github.com/go-delve/delve/pkg/proc/internal/ebpf"
) )
...@@ -130,16 +131,8 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error { ...@@ -130,16 +131,8 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error {
panic(ErrNativeBackendDisabled) panic(ErrNativeBackendDisabled)
} }
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) { func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) error) error {
panic(ErrNativeBackendDisabled) return proc.ErrHWBreakUnsupported
}
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)
} }
// Stopped returns whether the thread is stopped at // Stopped returns whether the thread is stopped at
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
sys "golang.org/x/sys/unix" sys "golang.org/x/sys/unix"
"github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/amd64util"
) )
// waitStatus is a synonym for the platform-specific WaitStatus // waitStatus is a synonym for the platform-specific WaitStatus
...@@ -133,14 +134,6 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error { ...@@ -133,14 +134,6 @@ func (t *nativeThread) restoreRegisters(sr proc.Registers) error {
return errors.New("not implemented") 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 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 ( ...@@ -11,6 +11,7 @@ import (
sys "golang.org/x/sys/unix" sys "golang.org/x/sys/unix"
"github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/amd64util"
) )
type waitStatus sys.WaitStatus type waitStatus sys.WaitStatus
...@@ -121,14 +122,6 @@ func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) { ...@@ -121,14 +122,6 @@ func (t *nativeThread) ReadMemory(data []byte, addr uint64) (n int, err error) {
return n, err 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 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 ( ...@@ -8,15 +8,3 @@ import (
func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error { func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
return fmt.Errorf("restore regs not supported on i386") 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 ...@@ -86,36 +86,3 @@ func (t *nativeThread) withDebugRegisters(f func(*amd64util.DebugRegisters) erro
} }
return err 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 { ...@@ -42,15 +42,3 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
} }
return restoreRegistersErr 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 ( ...@@ -7,6 +7,7 @@ import (
sys "golang.org/x/sys/windows" sys "golang.org/x/sys/windows"
"github.com/go-delve/delve/pkg/proc" "github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/amd64util"
"github.com/go-delve/delve/pkg/proc/winutil" "github.com/go-delve/delve/pkg/proc/winutil"
) )
...@@ -157,14 +158,25 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error { ...@@ -157,14 +158,25 @@ func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
return _SetThreadContext(t.os.hThread, savedRegs.(*winutil.AMD64Registers).Context) return _SetThreadContext(t.os.hThread, savedRegs.(*winutil.AMD64Registers).Context)
} }
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 context := winutil.NewCONTEXT()
} context.ContextFlags = _CONTEXT_DEBUG_REGISTERS
func (t *nativeThread) clearHardwareBreakpoint(addr uint64, wtype proc.WatchType, idx uint8) error { err := _GetThreadContext(t.os.hThread, context)
return proc.ErrHWBreakUnsupported if err != nil {
} return err
}
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)
}
func (t *nativeThread) findHardwareBreakpoint() (*proc.Breakpoint, error) { return nil
return nil, nil
} }
...@@ -5332,7 +5332,6 @@ func TestVariablesWithExternalLinking(t *testing.T) { ...@@ -5332,7 +5332,6 @@ func TestVariablesWithExternalLinking(t *testing.T) {
} }
func TestWatchpointsBasic(t *testing.T) { func TestWatchpointsBasic(t *testing.T) {
skipOn(t, "not implemented", "windows")
skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "freebsd")
skipOn(t, "not implemented", "darwin") skipOn(t, "not implemented", "darwin")
skipOn(t, "not implemented", "386") skipOn(t, "not implemented", "386")
...@@ -5378,7 +5377,6 @@ func TestWatchpointsBasic(t *testing.T) { ...@@ -5378,7 +5377,6 @@ func TestWatchpointsBasic(t *testing.T) {
} }
func TestWatchpointCounts(t *testing.T) { func TestWatchpointCounts(t *testing.T) {
skipOn(t, "not implemented", "windows")
skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "freebsd")
skipOn(t, "not implemented", "darwin") skipOn(t, "not implemented", "darwin")
skipOn(t, "not implemented", "386") skipOn(t, "not implemented", "386")
...@@ -5496,7 +5494,6 @@ func TestDwrapStartLocation(t *testing.T) { ...@@ -5496,7 +5494,6 @@ func TestDwrapStartLocation(t *testing.T) {
} }
func TestWatchpointStack(t *testing.T) { func TestWatchpointStack(t *testing.T) {
skipOn(t, "not implemented", "windows")
skipOn(t, "not implemented", "freebsd") skipOn(t, "not implemented", "freebsd")
skipOn(t, "not implemented", "darwin") skipOn(t, "not implemented", "darwin")
skipOn(t, "not implemented", "386") skipOn(t, "not implemented", "386")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册