Re: More trouble with i386 EFLAGS and ptrace

From: Linus Torvalds
Date: Sun Mar 06 2005 - 15:03:13 EST



On Sun, 6 Mar 2005, Daniel Jacobowitz wrote:
>
> The reason this happens is that when the inferior hits a breakpoint, the
> first thing GDB will do is remove the breakpoint, single-step past it, and
> reinsert it. So GDB does a PTRACE_SINGLESTEP, and the kernel invokes the
> signal handler (without single-step - good so far).

No, not good so far.

Yes, it cleared TF, but it saved eflags with TF set on-stack, even though
the TF was due to a TIF_SINGLESTEP (and was thus "temporary", not a real
flag). That's why you see the bogus SIGTRAP after returning from the
signal handler.

Now, we actually get this _right_ if the signal is due to a single-step,
because do_debug() will do:

if (likely(tsk->ptrace & PT_DTRACE)) {
tsk->ptrace &= ~PT_DTRACE;
regs->eflags &= ~TF_MASK;
}

but that's the only place we do that. So any _other_ signal won't do this,
and we'll enter the signal handler without checking the PT_DTRACE flag to
see if TF was a temporary thing from debugger rather than something the
program actually did on its own.

I _think_ your test-case would work right if you just moved that code from
the special-case in do_debug(), and moved it to the top of
setup_sigcontext() instead. I've not tested it, though, and haven't really
given it any "deep thought". Maybe somebody smarter can say "yeah, that's
obviously the right thing to do" or "no, that won't work because.."

Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/