提交 f88899ea 编写于 作者: H hengwu0 提交者: Derek Parker

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.
上级 b34936f5
...@@ -59,6 +59,13 @@ func (a *AMD64) BreakpointInstruction() []byte { ...@@ -59,6 +59,13 @@ func (a *AMD64) BreakpointInstruction() []byte {
return amd64BreakInstruction 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 // BreakpointSize returns the size of the
// breakpoint instruction on this architecture. // breakpoint instruction on this architecture.
func (a *AMD64) BreakpointSize() int { func (a *AMD64) BreakpointSize() int {
......
...@@ -11,6 +11,7 @@ type Arch interface { ...@@ -11,6 +11,7 @@ type Arch interface {
PtrSize() int PtrSize() int
MinInstructionLength() int MinInstructionLength() int
BreakpointInstruction() []byte BreakpointInstruction() []byte
BreakInstrMovesPC() bool
BreakpointSize() int BreakpointSize() int
DerefTLS() bool DerefTLS() bool
FixFrameUnwindContext(*frame.FrameContext, uint64, *BinaryInfo) *frame.FrameContext FixFrameUnwindContext(*frame.FrameContext, uint64, *BinaryInfo) *frame.FrameContext
......
...@@ -59,6 +59,13 @@ func (a *ARM64) BreakpointInstruction() []byte { ...@@ -59,6 +59,13 @@ func (a *ARM64) BreakpointInstruction() []byte {
return arm64BreakInstruction 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 // BreakpointSize returns the size of the
// breakpoint instruction on this architecture. // breakpoint instruction on this architecture.
func (a *ARM64) BreakpointSize() int { func (a *ARM64) BreakpointSize() int {
......
...@@ -119,9 +119,18 @@ func (t *Thread) SetCurrentBreakpoint(adjustPC bool) error { ...@@ -119,9 +119,18 @@ func (t *Thread) SetCurrentBreakpoint(adjustPC bool) error {
if err != nil { if err != nil {
return err 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 bp, ok := t.dbp.FindBreakpoint(pc, adjustPC); ok {
if err = t.SetPC(bp.Addr); err != nil { if adjustPC {
return err if err = t.SetPC(bp.Addr); err != nil {
return err
}
} }
t.CurrentBreakpoint = bp.CheckCondition(t) t.CurrentBreakpoint = bp.CheckCondition(t)
if t.CurrentBreakpoint.Breakpoint != nil && t.CurrentBreakpoint.Active { if t.CurrentBreakpoint.Breakpoint != nil && t.CurrentBreakpoint.Active {
......
...@@ -213,8 +213,8 @@ func Continue(dbp Process) error { ...@@ -213,8 +213,8 @@ func Continue(dbp Process) error {
case loc.Fn.Name == "runtime.breakpoint": case loc.Fn.Name == "runtime.breakpoint":
// In linux-arm64, PtraceSingleStep seems cannot step over BRK instruction // In linux-arm64, PtraceSingleStep seems cannot step over BRK instruction
// (linux-arm64 feature or kernel bug maybe). // (linux-arm64 feature or kernel bug maybe).
if arch, ok := curthread.Arch().(*ARM64); ok { if !curthread.Arch().BreakInstrMovesPC() {
curthread.SetPC(loc.PC + uint64(arch.BreakpointSize())) curthread.SetPC(loc.PC + uint64(curthread.Arch().BreakpointSize()))
} }
// Single-step current thread until we exit runtime.breakpoint and // Single-step current thread until we exit runtime.breakpoint and
// runtime.Breakpoint. // runtime.Breakpoint.
......
...@@ -79,7 +79,7 @@ Use the flags -s, -r and -b to specify which tests to run. Specifying nothing is ...@@ -79,7 +79,7 @@ Use the flags -s, -r and -b to specify which tests to run. Specifying nothing is
`, `,
Run: testCmd, 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: test.PersistentFlags().StringVarP(&TestSet, "test-set", "s", "", `Select the set of tests to run, one of either:
all tests all packages all tests all packages
basic tests proc, integration and terminal basic tests proc, integration and terminal
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册