Re: ptrace single-stepping change breaks Wine

Jesse Allen
2004-12-29T21:43:10Z

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

On Wed, 29 Dec 2004 12:04:57 -0800 (PST), Linus Torvalds
<torvalds@osdl.org> wrote:
> On Wed, 29 Dec 2004, Jesse Allen wrote:
> > > So does removing the conditional TF clear make everything work again?
> > >
> >
> > Yes, as long as TIF_SINGLESTEP is not set in set_singlestep().
>
> That may be a clue, if only because that makes absolutely _zero_ sense.
>
> Setting TIF_SINGLESTEP shouldn't actually matter in this case, since we
> set the TRAP_FLAG in eflags by hand anyway (and that's what TIF_SINGESTEP
> will just re-do when returning to user space).
>
> What TIF_SINGLESTEP _does_ do, however, is change how some other issues
> are reported to user space. In particular, it causes system call tracing
> (see arch/i386/kernel/ptrace.c: do_syscall_trace), and maybe it is _that_
> that messes up Wine.
>
> So instead of removing the setting of TIF_SINGLESTEP in set_singlestep(),
> can you test whether removing the _testing_ of it in do_syscall_trace()
> makes things happier for you? Hmm?
>

Yes, doing that does work. But I still have to remove the conditional
TF clear. Here's the diff now to show you.

Jesse

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: reverse_thread_flag_test.diff --]
[-- Type: text/x-diff; name="reverse_thread_flag_test.diff", Size: 955 bytes --]

--- linux/arch/i386/kernel/ptrace.c 2004-12-29 14:10:34.000000000 -0700
+++ linux-mod/arch/i386/kernel/ptrace.c 2004-12-29 14:22:33.000000000 -0700
@@ -568,8 +568,7 @@
audit_syscall_exit(current, regs->eax);
}

- if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
- !test_thread_flag(TIF_SINGLESTEP))
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
if (!(current->ptrace & PT_PTRACED))
return;
--- linux/arch/i386/kernel/signal.c 2004-12-29 14:10:34.000000000 -0700
+++ linux-mod/arch/i386/kernel/signal.c 2004-12-29 14:23:04.000000000 -0700
@@ -299,8 +299,8 @@
* don't want debugging to change state.
*/
eflags = regs->eflags;
- if (current->ptrace & PT_DTRACE)
- eflags &= ~TF_MASK;
+// if (current->ptrace & PT_DTRACE)
+// eflags &= ~TF_MASK;
err |= __put_user(eflags, &sc->eflags);
err |= __put_user(regs->esp, &sc->esp_at_signal);
err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);