This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Stepping off breakpoints in non-stop debugging mode


Daniel Jacobowitz <drow at false.org> writes:
>> - It seems that it is never necessary to have more than one thread
>>   doing displaced stepping at a time --- or else the assert in
>>   displaced_step_prepare would trigger --- but I don't see why this
>>   should be so.
>
> Isn't this because you haven't been testing combined with Vladimir's
> leave-breakpoints-inserted code?  resume is still going to force only
> the current thread to resume and wait, so the single step will finish
> before anything else gets a chance to hit a new breakpoint.  Combine
> those two patches, this will start happening.  Add non-stop debugging
> and it will happen even more.

I don't think Vlad's leave-breakpoints-inserted code will change that
aspect of the thread management.

I'm not sure that it must happen even in non-stop mode --- GDB can
step threads that have hit breakpoints past their breakpoints one at a
time.  I would *think* that would be the less ambitious approach.

>> +static int
>> +i386_syscall_p (gdb_byte *insn, ULONGEST *lengthp)
>> +{
>> +  if (insn[0] == 0xcd)
>> +    {
>> +      *lengthp = 2;
>> +      return 1;
>> +    }
>> +
>> +  return 0;
>> +}
>
> That's int, I assume.  May need sysenter / syscall, depending on the
> platform.

Right.  This shows up in sigstep.exp, where we single-step out of a
signal handler: that system call is interesting to us because it
actually does a transfer of control (back to the context that was
interrupted by the signal).  We mustn't relocate the PC after it's
done, because the PC has been set correctly by the syscall.

If signal handler trampolines can use sysenter / syscall, then we'll
need to recognize those, too.  (Can they?)

>> +  /* The list of issues to contend with here is taken from
>> +     resume_execution in arch/i386/kernel/kprobes.c, Linux 2.6.20.
>> +     Yay for Free Software!  */
>> +
>> +  /* Clear the TF flag in EFLAGS, which will always be set.  */
>> +  {
>> +    ULONGEST eflags;
>> +    regcache_cooked_read_unsigned (regs, I386_EFLAGS_REGNUM, &eflags);
>> +    eflags &= ~I386_TF_MASK;
>> +    regcache_cooked_write_unsigned (regs, I386_EFLAGS_REGNUM, eflags);
>> +  }
>
> Does this manual adjustment of TF apply to GDB?  The kernel is
> supposed to handle TF entirely inside ptrace, and expose the original
> %eflags to GDB (though various kernel versions have gotten this wrong,
> I believe it is right at last).  So if TF is set here, that means the
> program being debugged had TF set already.

It does apply to GDB!  You can write a statement that does "pushfl;
popl %0" and behaves differently depending on whether you continue
over it or step over it.

>> +  /* Relocate the %eip, if necessary.  */
>> +
>> +  /* In the case of absolute or indirect jump or call instructions, or
>> +     a return instruction, the new %eip needs no relocation.  */
>> +  if (i386_absolute_jmp_p (insn)
>> +      || i386_absolute_call_p (insn)
>> +      || i386_ret_p (insn))
>> +    ;
>> +
>> +  /* Except in the case of absolute or indirect jump or call
>> +     instructions, or a return instruction, the new eip is relative to
>> +     the displaced instruction; make it relative.  Well, signal
>> +     handler returns don't need relocation either, but we use the
>> +     value of %eip to recognize those; see below.  */
>> +  if (! i386_absolute_jmp_p (insn)
>> +      && ! i386_absolute_call_p (insn)
>> +      && ! i386_ret_p (insn))
>
> These two if statements look quite strange together.

Oops.  The first is detritus.  Thanks.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]