On Tue, 17 Jun 2025 11:06:49 +0200
Corinna Vinschen wrote:
> Hi Takashi,
>
> On May 28 21:52, Takashi Yano wrote:
> > +#ifdef __x86_64__
> > + /* When the Rip points to an instruction that causes an exception,
> > + modifying Rip and calling ResumeThread() may sometimes result in
> > + a crash. To prevent this, advance execution by a single instruction
> > + by setting the trap flag (TF) before calling ResumeThread(). This
> > + will trigger either STATUS_SINGLE_STEP or the exception caused by
> > + the instruction that Rip originally pointed to. By suspending the
> > + targeted thread within exception::handle(), Rip no longer points
> > + to the problematic instruction, allowing safe handling of the
> > + interrupt. As a result, Rip can be adjusted appropriately, and the
> > + thread can resume execution without unexpected crashes. */
> > + if (!inside_kernel (cx, true))
> > + {
> > + cx->EFlags |= 0x100; /* Set TF (setup single step execution) */
> > + SetThreadContext (*this, cx);
> > + suspend_on_exception = true;
> > + ResumeThread (*this);
> > + ULONG cnt = 0;
> > + NTSTATUS status;
> > + do
> > + {
> > + yield ();
> > + status = NtQueryInformationThread (*this, ThreadSuspendCount,
> > + &cnt, sizeof (cnt), NULL);
> > + }
> > + while (NT_SUCCESS (status) && cnt == 0);
> > + GetThreadContext (*this, cx);
>
> Doesn't this return cx->EFlags with the single step flag set? Otherwise
> this looks ok.
Thanks for reviewing.
IIUC, TF flag is automatically cleard when single step inturrupt is triggered.
I also checked the cx->EFlags at above GetThreadContext(), and the TF flag was
not set at that point.
--
Takashi Yano <[email protected]>