proc/native: fix SetCurrentBreakpoint on arm64

arm64 use hardware breakpoint, and it will not set PC to the next instruction like amd64. Let adjustPC always fasle in arm64, in case of infinite loop.
This commit is contained in:
hengwu0 2019-11-16 20:25:13 +08:00 committed by Derek Parker
parent b34936f5cc
commit f88899ea97
6 changed files with 29 additions and 5 deletions

@ -59,6 +59,13 @@ func (a *AMD64) BreakpointInstruction() []byte {
return amd64BreakInstruction
}
// BreakInstrMovesPC returns whether the
// breakpoint instruction will change the value
// of PC after being executed
func (a *AMD64) BreakInstrMovesPC() bool {
return true
}
// BreakpointSize returns the size of the
// breakpoint instruction on this architecture.
func (a *AMD64) BreakpointSize() int {

@ -11,6 +11,7 @@ type Arch interface {
PtrSize() int
MinInstructionLength() int
BreakpointInstruction() []byte
BreakInstrMovesPC() bool
BreakpointSize() int
DerefTLS() bool
FixFrameUnwindContext(*frame.FrameContext, uint64, *BinaryInfo) *frame.FrameContext

@ -59,6 +59,13 @@ func (a *ARM64) BreakpointInstruction() []byte {
return arm64BreakInstruction
}
// BreakInstrMovesPC returns whether the
// breakpoint instruction will change the value
// of PC after being executed
func (a *ARM64) BreakInstrMovesPC() bool {
return false
}
// BreakpointSize returns the size of the
// breakpoint instruction on this architecture.
func (a *ARM64) BreakpointSize() int {

@ -119,9 +119,18 @@ func (t *Thread) SetCurrentBreakpoint(adjustPC bool) error {
if err != nil {
return err
}
// If the breakpoint instruction does not change the value
// of PC after being executed we should look for breakpoints
// with bp.Addr == PC and there is no need to call SetPC
// after finding one.
adjustPC = adjustPC && t.Arch().BreakInstrMovesPC()
if bp, ok := t.dbp.FindBreakpoint(pc, adjustPC); ok {
if err = t.SetPC(bp.Addr); err != nil {
return err
if adjustPC {
if err = t.SetPC(bp.Addr); err != nil {
return err
}
}
t.CurrentBreakpoint = bp.CheckCondition(t)
if t.CurrentBreakpoint.Breakpoint != nil && t.CurrentBreakpoint.Active {

@ -213,8 +213,8 @@ func Continue(dbp Process) error {
case loc.Fn.Name == "runtime.breakpoint":
// In linux-arm64, PtraceSingleStep seems cannot step over BRK instruction
// (linux-arm64 feature or kernel bug maybe).
if arch, ok := curthread.Arch().(*ARM64); ok {
curthread.SetPC(loc.PC + uint64(arch.BreakpointSize()))
if !curthread.Arch().BreakInstrMovesPC() {
curthread.SetPC(loc.PC + uint64(curthread.Arch().BreakpointSize()))
}
// Single-step current thread until we exit runtime.breakpoint and
// runtime.Breakpoint.

@ -79,7 +79,7 @@ Use the flags -s, -r and -b to specify which tests to run. Specifying nothing is
`,
Run: testCmd,
}
test.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "Verbose tests")
test.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", true, "Verbose tests")
test.PersistentFlags().StringVarP(&TestSet, "test-set", "s", "", `Select the set of tests to run, one of either:
all tests all packages
basic tests proc, integration and terminal