Raise a proper SIGTRAP / TRAP_TRACE signal for a PT_STEP step on arm.

Previously, a step by PT_STEP resulted in no signal being raised to
the debugger so that a step was silently completed with the program
continuing to execute after the step.  Fix by raising a SIGTRAP
signal with TRAP_TRACE as the signal code.

To simplify the error handling cases (if ptrace_clear_single_step()
fails, etc.) move the handling of PTRACE_BREAKPOINT into the
gdb_trapper() function.  If ptrace_clear_single_step() fails,
gdb_trapper() won't claim the fault, and the default case of
SIGILL / ILL_OPC will be used.

Differential Revision:	https://reviews.freebsd.org/D16100
This commit is contained in:
John Baldwin 2018-07-25 18:11:37 +00:00
parent d904ce8a52
commit 433390a0ca
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336722

View File

@ -144,6 +144,7 @@ gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
{
struct thread *td;
ksiginfo_t ksi;
int error;
td = (curthread == NULL) ? &thread0 : curthread;
@ -162,6 +163,27 @@ gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
#endif
#endif
}
if (code == FAULT_USER) {
/* TODO: No support for ptrace from Thumb-2 */
if ((frame->tf_spsr & PSR_T) == 0 &&
insn == PTRACE_BREAKPOINT) {
PROC_LOCK(td->td_proc);
_PHOLD(td->td_proc);
error = ptrace_clear_single_step(td);
_PRELE(td->td_proc);
PROC_UNLOCK(td->td_proc);
if (error == 0) {
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_TRACE;
ksi.ksi_addr = (u_int32_t *)addr;
trapsignal(td, &ksi);
return (0);
}
}
}
return 1;
}
@ -191,7 +213,6 @@ undefinedinstruction(struct trapframe *frame)
int fault_code;
int coprocessor;
struct undefined_handler *uh;
int error;
#ifdef VERBOSE_ARM32
int s;
#endif
@ -305,26 +326,6 @@ undefinedinstruction(struct trapframe *frame)
fault_code) == 0)
break;
if (fault_code & FAULT_USER) {
/* TODO: No support for ptrace from Thumb-2 */
if ((frame->tf_spsr & PSR_T) == 0 &&
fault_instruction == PTRACE_BREAKPOINT) {
PROC_LOCK(td->td_proc);
_PHOLD(td->td_proc);
error = ptrace_clear_single_step(td);
_PRELE(td->td_proc);
PROC_UNLOCK(td->td_proc);
if (error != 0) {
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_ILLOPC;
ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
trapsignal(td, &ksi);
}
return;
}
}
if (uh == NULL && (fault_code & FAULT_USER)) {
/* Fault has not been handled */
ksiginfo_init_trap(&ksi);