* [PATCH] x86-64 singlestep through sigreturn system call
@ 2004-07-13 0:22 Roland McGrath
2004-07-13 7:23 ` Andi Kleen
0 siblings, 1 reply; 11+ messages in thread
From: Roland McGrath @ 2004-07-13 0:22 UTC (permalink / raw)
To: Andrew Morton, Andi Kleen, Linus Torvalds
Cc: Linux Kernel Mailing List, Jim Paradis, Andrew Cagney
With Davide Libenzi's patch for i386 and my follow-on patch for x86-64's
ia32 support, single-stepping through any system call correctly traps
immediately on return to user mode. I still don't know why the same
problem doesn't arise for `syscall'/`sysret' on native 64-bit x86-64, and
would like someone to point me at what I misunderstood in the chip manuals.
But, there is a problem in the case of the rt_sigreturn system call on
native x86-64. When using PTRACE_SINGLESTEP to step into an rt_sigreturn
system call and the sigcontext being restored does not have TF set in its
%eflags, then we miss the single-step trap. This makes gdb unhappy.
Here is a test program to run under gdb. Set a breakpoint on "keeper".
When SIGSEGV hits, just continue to let the program handle it. When you
get into "keeper", do "display/i $pc" to see what's going on and then do
"stepi" repeatedly to get out of the handler and into the signal handler
trampoline as it makes the rt_sigreturn system call. When you step into
the `syscall' instruction, you will lose control. Rather than stopping
immediately, the program will reexecute the faulting instruction and take a
second SIGSEGV.
#include <signal.h>
#include <stdlib.h>
#include <string.h>
extern void
keeper (int sig)
{
}
volatile long v1 = 0;
volatile long v2 = 0;
volatile long v3 = 0;
extern long
bowler (void)
{
/* Try to read address zero. Do it in a slightly convoluted way so
that more than one instruction is used. */
return *(char *) (v1 + v2 + v3);
}
int
main ()
{
static volatile int i;
struct sigaction act;
memset (&act, 0, sizeof act);
act.sa_handler = keeper;
sigaction (SIGSEGV, &act, NULL);
bowler ();
return 0;
}
This patch fixes the problem by forcing a fake single-step trap at the end
of rt_sigreturn when PTRACE_SINGLESTEP was used to enter the system call.
Thanks,
Roland
Signed-off-by: Roland McGrath <roland@redhat.com>
Index: linux-2.6/arch/x86_64/kernel/signal.c
===================================================================
RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/signal.c,v
retrieving revision 1.23
diff -b -p -u -r1.23 signal.c
--- linux-2.6/arch/x86_64/kernel/signal.c 31 May 2004 03:08:04 -0000 1.23
+++ linux-2.6/arch/x86_64/kernel/signal.c 12 Jul 2004 22:14:07 -0000
@@ -92,6 +92,7 @@ static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned long *prax)
{
unsigned int err = 0;
+ unsigned int caller_eflags;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -112,6 +113,7 @@ restore_sigcontext(struct pt_regs *regs,
{
unsigned int tmpflags;
err |= __get_user(tmpflags, &sc->eflags);
+ caller_eflags = regs->eflags;
regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
regs->orig_rax = -1; /* disable syscall checks */
}
@@ -128,6 +130,22 @@ restore_sigcontext(struct pt_regs *regs,
}
err |= __get_user(*prax, &sc->rax);
+
+ if (!err && unlikely(caller_eflags & X86_EFLAGS_TF) &&
+ (current->ptrace & (PT_PTRACED|PT_DTRACE)) == (PT_PTRACED|PT_DTRACE)) {
+ /*
+ * If ptrace single-stepped into the sigreturn system call,
+ * then fake a single-step trap before we resume the restored
+ * context.
+ */
+ siginfo_t info;
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void *)regs->rip;
+ force_sig_info(SIGTRAP, &info, current);
+ }
+
return err;
badframe:
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-13 0:22 [PATCH] x86-64 singlestep through sigreturn system call Roland McGrath @ 2004-07-13 7:23 ` Andi Kleen 2004-07-15 0:56 ` Roland McGrath 0 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-07-13 7:23 UTC (permalink / raw) To: Roland McGrath; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney On Mon, 12 Jul 2004 17:22:30 -0700 Roland McGrath <roland@redhat.com> wrote: > This patch fixes the problem by forcing a fake single-step trap at the end > of rt_sigreturn when PTRACE_SINGLESTEP was used to enter the system call. I don't like this very much, see previous mail. If you really wanted to do it: Wouldn't it be simpler to just copy the TF bit from the previous Eflags? This special case looks quite ugly. -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-13 7:23 ` Andi Kleen @ 2004-07-15 0:56 ` Roland McGrath 2004-07-15 5:46 ` Andi Kleen 0 siblings, 1 reply; 11+ messages in thread From: Roland McGrath @ 2004-07-15 0:56 UTC (permalink / raw) To: Andi Kleen; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney > > This patch fixes the problem by forcing a fake single-step trap at the end > > of rt_sigreturn when PTRACE_SINGLESTEP was used to enter the system call. > > I don't like this very much, see previous mail. The previous mail addressed the subject of changing the behavior of i386 processes, where single-stepping any system call misses a trap. The native x86-64 behavior is different, and so this issue is really separate from that one. By the way, I would love it if you could explain to me with references to the x86-64 chip documentation why restoring TF with sysret seems to trap before executing the next user instruction in 64-bit mode, while restoring TF with sysexit to 32-bit user mode behaves like native 32-bit mode (as documented) and executes one instruction before taking the single-step trap. Anyway, on native x86-64 single-stepping into `syscall' already works like a user would expect, and takes a single-step trap immediately on return from the system call before executing the first user instruction. Only stepping into an `rt_sigreturn' call behaves otherwise. > If you really wanted to do it: > > Wouldn't it be simpler to just copy the TF bit from the previous Eflags? > This special case looks quite ugly. I would expect that to work from the behavior I think I see with other system calls. But I've tried it and it doesn't work. Setting TF this way behaves like the i386 does: it executes one user instruction at the restored PC and then traps. I certainly find this confusing, but as I said above I still haven't explained to myself why it doesn't behave that way for normal system calls (that don't change the PC being returned to). Thanks, Roland ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-15 0:56 ` Roland McGrath @ 2004-07-15 5:46 ` Andi Kleen 2004-07-15 21:13 ` Roland McGrath 0 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-07-15 5:46 UTC (permalink / raw) To: Roland McGrath; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney, discuss On Wed, 14 Jul 2004 17:56:26 -0700 Roland McGrath <roland@redhat.com> wrote: [adding discuss@x86-64.org, maybe someone there knows more about the SYSRET behaviour] > > > This patch fixes the problem by forcing a fake single-step trap at the end > > > of rt_sigreturn when PTRACE_SINGLESTEP was used to enter the system call. > > > > I don't like this very much, see previous mail. > > The previous mail addressed the subject of changing the behavior of i386 > processes, where single-stepping any system call misses a trap. The native > x86-64 behavior is different, and so this issue is really separate from > that one. By the way, I would love it if you could explain to me with > references to the x86-64 chip documentation why restoring TF with sysret > seems to trap before executing the next user instruction in 64-bit mode, > while restoring TF with sysexit to 32-bit user mode behaves like native > 32-bit mode (as documented) and executes one instruction before taking the > single-step trap. I don't think it's documented anywhere. Even the old SYSCALL/SYSRET Athlon application note doesn't say anything about how single step is supposed to work with this. It's probably an artifact of the first implementation that has been faithfully reproduced since then. > Anyway, on native x86-64 single-stepping into `syscall' already works like > a user would expect, and takes a single-step trap immediately on return > from the system call before executing the first user instruction. Only > stepping into an `rt_sigreturn' call behaves otherwise. and a few other calls who use iret, like iopl() or sigaltstack(). Anyways, I don't have any plans to change the 64bit behaviour. gdb will have to live with a few minor inconsistencies as price for faster system calls. > > If you really wanted to do it: > > > > Wouldn't it be simpler to just copy the TF bit from the previous Eflags? > > This special case looks quite ugly. > > I would expect that to work from the behavior I think I see with other > system calls. But I've tried it and it doesn't work. Setting TF this way > behaves like the i386 does: it executes one user instruction at the > restored PC and then traps. I certainly find this confusing, but as I said > above I still haven't explained to myself why it doesn't behave that way > for normal system calls (that don't change the PC being returned to). The normal syscalls use SYSRET, the special syscalls use IRET. That's required because SYSRET cannot restore all registers, so sometimes a slow path out must be taken. -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-15 5:46 ` Andi Kleen @ 2004-07-15 21:13 ` Roland McGrath 2004-07-15 22:06 ` Andi Kleen 0 siblings, 1 reply; 11+ messages in thread From: Roland McGrath @ 2004-07-15 21:13 UTC (permalink / raw) To: Andi Kleen; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney, discuss > Anyways, I don't have any plans to change the 64bit behaviour. gdb will > have to live with a few minor inconsistencies as price for faster system > calls. My patch doesn't slow anything down beyond one comparison and branch not taken in the rt_sigreturn system call. Does that negligible meaning of "faster" really warrant the inconsistent user behavior? Thanks, Roland ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-15 21:13 ` Roland McGrath @ 2004-07-15 22:06 ` Andi Kleen 2004-07-15 23:57 ` Roland McGrath 0 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-07-15 22:06 UTC (permalink / raw) To: Roland McGrath; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney, discuss On Thu, 15 Jul 2004 14:13:15 -0700 Roland McGrath <roland@redhat.com> wrote: > > Anyways, I don't have any plans to change the 64bit behaviour. gdb will > > have to live with a few minor inconsistencies as price for faster system > > calls. > > My patch doesn't slow anything down beyond one comparison and branch not > taken in the rt_sigreturn system call. Does that negligible meaning of > "faster" really warrant the inconsistent user behavior? I meant as a general side effect of using SYSRET and not always IRET. In the later case it would be consistently like i386. Anyways, even if I applied your patch there would be still inconsistency because there are several other system calls that use IRET. So I don't see much advantage in adding a special case just for sigreturn. -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-15 22:06 ` Andi Kleen @ 2004-07-15 23:57 ` Roland McGrath 0 siblings, 0 replies; 11+ messages in thread From: Roland McGrath @ 2004-07-15 23:57 UTC (permalink / raw) To: Andi Kleen; +Cc: akpm, torvalds, linux-kernel, jparadis, cagney, discuss > Anyways, even if I applied your patch there would be still inconsistency > because there are several other system calls that use IRET. So I don't > see much advantage in adding a special case just for sigreturn. Now that I see that the difference is due to iret being used, I have a different solution that handles all cases. The following patch replaces both my previous patch for x86-64 native behavior and my patch for x86-64's ia32 support. This patch just directly clones Davide Libenzi's i386 code for x86-64 in both 64-bit and 32-bit cases. With this, the behavior of single-stepping all system calls is consistent. The syscall exit tracing caused by TIF_SINGLESTEP is superfluous in the case of sysret returns, but harmlessly so (since continuing afterward with PTRACE_CONT will have cleared TF as well as TIF_SINGLESTEP). I figured that little bit of extra processing in the single-step case was better than adding code to ignore the flag in the sysret case. Thanks, Roland Signed-off-by: Roland McGrath <roland@redhat.com> Index: linux-2.6/arch/x86_64/kernel/entry.S =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/entry.S,v retrieving revision 1.22 diff -b -p -u -r1.22 entry.S --- linux-2.6/arch/x86_64/kernel/entry.S 12 Apr 2004 20:29:12 -0000 1.22 +++ linux-2.6/arch/x86_64/kernel/entry.S 15 Jul 2004 23:45:59 -0000 @@ -297,7 +297,7 @@ int_very_careful: sti SAVE_REST /* Check for syscall exit trace */ - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),%edx + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx jz int_signal pushq %rdi leaq 8(%rsp),%rdi # &ptregs -> arg1 Index: linux-2.6/arch/x86_64/kernel/ptrace.c =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/ptrace.c,v retrieving revision 1.16 diff -b -p -u -r1.16 ptrace.c --- linux-2.6/arch/x86_64/kernel/ptrace.c 31 May 2004 03:07:42 -0000 1.16 +++ linux-2.6/arch/x86_64/kernel/ptrace.c 15 Jul 2004 23:56:44 -0000 @@ -88,6 +88,7 @@ void ptrace_disable(struct task_struct * { long tmp; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); } @@ -344,6 +345,7 @@ asmlinkage long sys_ptrace(long request, set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); else clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET); @@ -395,6 +397,7 @@ asmlinkage long sys_ptrace(long request, ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; @@ -416,6 +419,7 @@ asmlinkage long sys_ptrace(long request, } tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -528,7 +532,8 @@ asmlinkage void syscall_trace_leave(stru if (unlikely(current->audit_context)) audit_syscall_exit(current, regs->rax); - 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(regs); } ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <2imAA-4n7-49@gated-at.bofh.it>]
[parent not found: <2iosE-5Kb-17@gated-at.bofh.it>]
* Re: [PATCH] x86-64 singlestep through sigreturn system call [not found] ` <2iosE-5Kb-17@gated-at.bofh.it> @ 2004-07-17 11:12 ` Andi Kleen 2004-07-22 2:16 ` Roland McGrath 0 siblings, 1 reply; 11+ messages in thread From: Andi Kleen @ 2004-07-17 11:12 UTC (permalink / raw) To: Roland McGrath; +Cc: linux-kernel Roland McGrath <roland@redhat.com> writes: >> Anyways, even if I applied your patch there would be still inconsistency >> because there are several other system calls that use IRET. So I don't >> see much advantage in adding a special case just for sigreturn. > > Now that I see that the difference is due to iret being used, I have a > different solution that handles all cases. The following patch replaces > both my previous patch for x86-64 native behavior and my patch for x86-64's > ia32 support. This patch just directly clones Davide Libenzi's i386 code > for x86-64 in both 64-bit and 32-bit cases. With this, the behavior of > single-stepping all system calls is consistent. Hmm, but now the behaviour for 32bit processes is different from the native 32bit kernel, since 32bit didn't apply any patch so far AFAIK. If you send me a patch that just changes the behaviour of 64bit IRET I would apply it. -Andi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-17 11:12 ` Andi Kleen @ 2004-07-22 2:16 ` Roland McGrath 2004-07-22 6:11 ` Andrew Morton 0 siblings, 1 reply; 11+ messages in thread From: Roland McGrath @ 2004-07-22 2:16 UTC (permalink / raw) To: Andi Kleen; +Cc: linux-kernel, Andrew Morton > Hmm, but now the behaviour for 32bit processes is different from the > native 32bit kernel, since 32bit didn't apply any patch so far AFAIK. Well, I was (and am) advocating that Davide's patch for native 32-bit be applied as well. If it is, then my last x86-64 patch covers both 32-bit and 64-bit cases with minimal cruft. In particular, 2.6.8-rc1-mm1 contains Davide's patch and both of my earlier x86-64 patches. I hope Andrew will replace those two patches with the later cleaner single x86-64 patch. If Linus merges that patch of mine and Davide's i386 patch, I will be a happy camper. > If you send me a patch that just changes the behaviour of 64bit > IRET I would apply it. Ok. This is just one line different from the patch I just posted. In 32-bit processes, some ptrace operations will superfluously clear a flag bit that can never be set, rather than test another flag bit to branch around doing it. If/when the native 32-bit behavior fix gets merged in and you want to match it, just remove `if (!test_tsk_thread_flag(child, TIF_IA32))' (which is the same as reverting this patch and applying the earlier one). Thanks, Roland Index: linux-2.6/arch/x86_64/kernel/entry.S =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/entry.S,v retrieving revision 1.22 diff -b -p -u -r1.22 entry.S --- linux-2.6/arch/x86_64/kernel/entry.S 12 Apr 2004 20:29:12 -0000 1.22 +++ linux-2.6/arch/x86_64/kernel/entry.S 15 Jul 2004 23:45:59 -0000 @@ -297,7 +297,7 @@ int_very_careful: sti SAVE_REST /* Check for syscall exit trace */ - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),%edx + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx jz int_signal pushq %rdi leaq 8(%rsp),%rdi # &ptregs -> arg1 Index: linux-2.6/ptrace.c =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/ptrace.c,v retrieving revision 1.16 diff -u -b -p -r1.16 ptrace.c --- linux-2.6/ptrace.c 31 May 2004 03:07:42 -0000 1.16 +++ linux-2.6/ptrace.c 22 Jul 2004 00:42:06 -0000 @@ -88,6 +88,7 @@ void ptrace_disable(struct task_struct * { long tmp; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); } @@ -344,6 +345,7 @@ asmlinkage long sys_ptrace(long request, set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); else clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET); @@ -395,6 +397,7 @@ asmlinkage long sys_ptrace(long request, ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; @@ -416,6 +419,8 @@ asmlinkage long sys_ptrace(long request, } tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); + if (!test_tsk_thread_flag(child, TIF_IA32)) + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -528,7 +533,8 @@ asmlinkage void syscall_trace_leave(stru if (unlikely(current->audit_context)) audit_syscall_exit(current, regs->rax); - 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(regs); } ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-22 2:16 ` Roland McGrath @ 2004-07-22 6:11 ` Andrew Morton 2004-07-22 22:58 ` Roland McGrath 0 siblings, 1 reply; 11+ messages in thread From: Andrew Morton @ 2004-07-22 6:11 UTC (permalink / raw) To: Roland McGrath; +Cc: ak, linux-kernel Roland McGrath <roland@redhat.com> wrote: > > > Hmm, but now the behaviour for 32bit processes is different from the > > native 32bit kernel, since 32bit didn't apply any patch so far AFAIK. > > Well, I was (and am) advocating that Davide's patch for native 32-bit be > applied as well. If it is, then my last x86-64 patch covers both 32-bit > and 64-bit cases with minimal cruft. In particular, 2.6.8-rc1-mm1 contains > Davide's patch and both of my earlier x86-64 patches. I hope Andrew will > replace those two patches with the later cleaner single x86-64 patch. If > Linus merges that patch of mine and Davide's i386 patch, I will be a happy > camper. Am now all confused. Please tell me which patches to drop, and ensure that I have the replacement patches, if any. Thanks. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] x86-64 singlestep through sigreturn system call 2004-07-22 6:11 ` Andrew Morton @ 2004-07-22 22:58 ` Roland McGrath 0 siblings, 0 replies; 11+ messages in thread From: Roland McGrath @ 2004-07-22 22:58 UTC (permalink / raw) To: Andrew Morton; +Cc: ak, linux-kernel > Am now all confused. Please tell me which patches to drop, and ensure that > I have the replacement patches, if any. Thanks. Please drop these two: x86-64-singlestep-through-sigreturn-system-call.patch x86-64-support-for-singlestep-into-32-bit-system-calls.patch and replace them with the following patch, which I first posted last week. With this, x86-64's behavior for ia32 matches the native i386 behavior given really-ptrace-single-step-2.patch, and x86-64's native behavior is similarly improved. The two patches above together do the same as this one alone, but this one is cleaner. Thanks, Roland Index: linux-2.6/arch/x86_64/kernel/entry.S =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/entry.S,v retrieving revision 1.22 diff -b -p -u -r1.22 entry.S --- linux-2.6/arch/x86_64/kernel/entry.S 12 Apr 2004 20:29:12 -0000 1.22 +++ linux-2.6/arch/x86_64/kernel/entry.S 15 Jul 2004 23:45:59 -0000 @@ -297,7 +297,7 @@ int_very_careful: sti SAVE_REST /* Check for syscall exit trace */ - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),%edx + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx jz int_signal pushq %rdi leaq 8(%rsp),%rdi # &ptregs -> arg1 Index: linux-2.6/arch/x86_64/kernel/ptrace.c =================================================================== RCS file: /home/roland/redhat/bkcvs/linux-2.5/arch/x86_64/kernel/ptrace.c,v retrieving revision 1.16 diff -b -p -u -r1.16 ptrace.c --- linux-2.6/arch/x86_64/kernel/ptrace.c 31 May 2004 03:07:42 -0000 1.16 +++ linux-2.6/arch/x86_64/kernel/ptrace.c 15 Jul 2004 23:56:44 -0000 @@ -88,6 +88,7 @@ void ptrace_disable(struct task_struct * { long tmp; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); } @@ -344,6 +345,7 @@ asmlinkage long sys_ptrace(long request, set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); else clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET); @@ -395,6 +397,7 @@ asmlinkage long sys_ptrace(long request, ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG; @@ -416,6 +419,7 @@ asmlinkage long sys_ptrace(long request, } tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG; put_stack_long(child, EFL_OFFSET, tmp); + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -528,7 +532,8 @@ asmlinkage void syscall_trace_leave(stru if (unlikely(current->audit_context)) audit_syscall_exit(current, regs->rax); - 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(regs); } ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-07-22 22:59 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-13 0:22 [PATCH] x86-64 singlestep through sigreturn system call Roland McGrath
2004-07-13 7:23 ` Andi Kleen
2004-07-15 0:56 ` Roland McGrath
2004-07-15 5:46 ` Andi Kleen
2004-07-15 21:13 ` Roland McGrath
2004-07-15 22:06 ` Andi Kleen
2004-07-15 23:57 ` Roland McGrath
[not found] <2imAA-4n7-49@gated-at.bofh.it>
[not found] ` <2iosE-5Kb-17@gated-at.bofh.it>
2004-07-17 11:12 ` Andi Kleen
2004-07-22 2:16 ` Roland McGrath
2004-07-22 6:11 ` Andrew Morton
2004-07-22 22:58 ` Roland McGrath
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox