ptrace + Warcraft 3 issues remain (2.6.10)

Jesse Allen the3dfxdude at gmail.com
Tue Dec 28 15:49:25 CST 2004


Last I reported on Warcraft 3 with the ptrace changes in 2.6.10-rc3 is
that it made some improvement, but still doesn't work.  I'll will
describe in detail what I know now.

Since the changes in 2.6.10-rc3, Linus made a very good clean up of
ptrace.c and signal.c in arch/i386/kernel.  I don't want to
necessarily reverse all these changes because they are good changes
(ie easier to understand and hack now).  So I hacked the kernel to
change what is necessary to make the game run again.  I have attached
the patch against 2.6.10 to show the required changes.

Comments on what I have learned about the 3 ptrace changes (see my
original report):
#1 ptrace.c

In set_singlestep() and clear_singlestep(), the flag TIF_SINGLESTEP is
now set and cleared.  In the header file in
include/asm-i386/thread_info.h, it seems to indicate to me that it is
an internal flag to remember to re enable single-stepping for a thread
on returning to the program.  While speaking to my brother on this, we
believe that this change was done correctly.  But this change alone
will break the game.  I have looked in both wine for PTRACE_SINGLESTEP
to see what it does and in the kernel for TIF_SINGLESTEP.  Since
set/clear TIF_SINGLESTEP causes the problem, I really need more
information on everything about TIF_SINGLESTEP.

#2 signal.c - Not single-stepping into signal handlers unless the
tracer requests it

Previous to 2.6.9-rc2,  my understanding is that a call to
setup_frame() would clear the trap flag in preparation for a signal
delivery.  Roland made a slight tweak to it and an example of it is
this:
        if (regs->eflags & TF_MASK) {
                if (current->ptrace & PT_PTRACED) {
                        ptrace_notify(SIGTRAP);
                } else {
                        regs->eflags &= ~TF_MASK;
                }
        }

Linus later changed it to:
        /*
         * Clear TF when entering the signal handler, but
         * notify any tracer that was single-stepping it.
         * The tracer may want to single-step inside the
         * handler too.
         */
        if (regs->eflags & TF_MASK) {
                regs->eflags &= ~TF_MASK;
                if (current->ptrace & PT_DTRACE)
                        ptrace_notify(SIGTRAP);
        }

In 2.6.10, this new piece of code actually works with Warcraft III.  I
no longer have to reverse this change.  The result is obvious because
it makes it so you don't automatically single step into the handler,
which wine doesn't really want.

#3 signal.c - Clearing the trap flag if being traced by debugger in
setup_sigcontext()

For some reason, Warcraft III doesn't work if it is cleared here.  I
have no idea if this TF clear is really necessary.  However,
everything I've read on this seems to indicate to me that this change
is important, so I need to find out what this causes to the game.

I captured a log of the seh debug messages because I think this is may
be where to look.  I also hacked in to display trace messages in
wine's dlls/ntdll/signal_i386.c showing eflags and whether TF is
cleared in trap_handler() and raise_trap_exception().  I ran the game
under 2.6.10 and the modded 2.6.10, to capture the working version,
and the failing version.   The results are fairly nonrandom and
comparable and you can identify differences.  Unfortunately, I cannot
upload them at the moment because my connection is slow and the files
are large.  I'll upload it another time.

Jesse
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ptrace-reverse.diff
Type: text/x-diff
Size: 1398 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20041228/a82f32c1/ptrace-reverse.bin


More information about the wine-devel mailing list