From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28566 invoked by alias); 10 Dec 2007 23:05:16 -0000 Received: (qmail 28510 invoked by uid 22791); 10 Dec 2007 23:05:09 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 10 Dec 2007 23:05:03 +0000 Received: (qmail 32402 invoked from network); 10 Dec 2007 23:05:01 -0000 Received: from unknown (HELO localhost) (jimb@127.0.0.2) by mail.codesourcery.com with ESMTPA; 10 Dec 2007 23:05:01 -0000 To: gdb@sourceware.org Subject: Re: Stepping off breakpoints in non-stop debugging mode References: <20071208170359.GA8777@caradoc.them.org> From: Jim Blandy Date: Mon, 10 Dec 2007 23:05:00 -0000 In-Reply-To: <20071208170359.GA8777@caradoc.them.org> (Daniel Jacobowitz's message of "Sat, 8 Dec 2007 12:03:59 -0500") Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00072.txt.bz2 Daniel Jacobowitz 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.