[IA64] enable singlestep on system call
As is pointed out in http://www.gelato.org/community/view_linear.php?id=1_1036&from=authors&value=Ian%20Wienand#1_1039, if single step on break instruction, the break fault has higher priority than the single-step trap. When the break fault handler is entered, it advances the IP by 1 instruction so break instruction single-stepping is skipped, actually it is next instruction which is single stepped. This patch modifies this, it adds TIF_SINGLESTEP bit for thread flags, and generate a fake sigtrap when single stepping break instruction. Test case in attachment can verify this. Any comments is welcome. Signed-off-by: bibo, mao <bibo.mao@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
@@ -1405,6 +1405,7 @@ ptrace_disable (struct task_struct *child)
|
||||
struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
|
||||
|
||||
/* make sure the single step/taken-branch trap bits are not set: */
|
||||
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
child_psr->ss = 0;
|
||||
child_psr->tb = 0;
|
||||
}
|
||||
@@ -1525,6 +1526,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
|
||||
* Make sure the single step/taken-branch trap bits
|
||||
* are not set:
|
||||
*/
|
||||
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
ia64_psr(pt)->ss = 0;
|
||||
ia64_psr(pt)->tb = 0;
|
||||
|
||||
@@ -1556,6 +1558,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
|
||||
goto out_tsk;
|
||||
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
if (request == PTRACE_SINGLESTEP) {
|
||||
ia64_psr(pt)->ss = 1;
|
||||
} else {
|
||||
@@ -1595,13 +1598,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
syscall_trace (void)
|
||||
{
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return;
|
||||
/*
|
||||
* The 0x80 provides a way for the tracing parent to
|
||||
* distinguish between a syscall stop and SIGTRAP delivery.
|
||||
@@ -1664,7 +1663,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
|
||||
audit_syscall_exit(success, result);
|
||||
}
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
|| test_thread_flag(TIF_SINGLESTEP))
|
||||
&& (current->ptrace & PT_PTRACED))
|
||||
syscall_trace();
|
||||
}
|
||||
|
Reference in New Issue
Block a user