public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Cagney <cagney@redhat.com>
To: Mark Wielaard <mark@klomp.org>
Cc: frysk@sourceware.org
Subject: Re: Breakpoint stepping
Date: Thu, 05 Jul 2007 18:37:00 -0000	[thread overview]
Message-ID: <468D3A87.4020205@redhat.com> (raw)
In-Reply-To: <1183573205.3598.157.camel@dijkstra.wildebeest.org>

Mark,

Can I suggest adding this, or something based on it, to 
frysk.proc.live.package.html?  It's this useful! information we should 
be accumulating in the source tree.

Andrew

Mark Wielaard wrote:
> As you might have noticed over the last week I have dropped in the new
> breakpoint stepping framework (or hopefully you didn't notice since I
> did try to do it in chunks that all had no detectable functional
> behavior changes). This is an update to my previous general stepping
> overview http://sourceware.org/ml/frysk/2007-q2/msg00283.html
> and a request for review of the next steps with regard to the
> instruction parsers, testframework and what to use as ssol area.
>
> The main difference with the previous stepping overview regarding the
> ptrace state machine is that there is now an explicit Stepping state,
> which is a sub-state of Running and that Running.sendContinue() now not
> only determines how to instruct ptrace to continue the task, but also
> returns a different Running state based on whether or not we asked for a
> continue or step-continue. This makes interpreting the cause of the trap
> event we subsequently expect to get easier. This was previously recorded
> as a field in the Task itself.
>
> With respect to breakpoints the ptrace task states have been adapted to
> all call setupSteppingBreakpoint() after a breakpoint hit has been
> detected, which makes sure the PC is setup correctly (which previously
> could be off by one on some architectures) and to mark the Task as being
> at that particular breakpoint (this is still kept as Task field for now)
> and to not actually call Breakpoint.prepareStep(), which is now handled
> in Running.sendContinue(). In the previous version when reset-breakpoint
> stepping was used another task could miss the breakpoint if the Task
> moved into a Blocked state before continuing.
>
> All the logic of how to breakpoint step has been moved into the
> Breakpoint class that checks the properties of a new Instruction class
> object which is created by the Isa through an instruction parser before
> the breakpoint is inserted at a given location (previously we
> represented instructions just as a byte[]). An Instruction knows how
> long the instruction is, which bytes it represents, whether it can be
> single stepped out of line and how to set that up given the original pc
> location and an alternative address, plus any fixups that are needed to
> the Task afterwards (and it has a notion of whether or not the
> Instruction can be simulated, but that isn't currently used, see below).
> A Breakpoint ties an Instruction to a particular address and Proc (and
> Tasks can have zero or more Breakpoints, they share the same Breakpoint
> on the same address with other Tasks of a Proc and when no Tasks of a
> Proc has an Breakpoint at a particular address anymore the Breakpoint is
> removed).
>
> For stepping the Breakpoint the Running.sendContinue() method first
> calls Breakpoint.prepareStep(), then signals ptrace to do a single step
> of the Task, putting the Task in Stepping state and then in
> handleTrapEvent() calls Breakpoint.stepDone(). prepareStep() queries the
> capabilities of the Instruction at the pc address and depending on that
> either sets things up for doing a step out of line, simulate the
> instruction (but none of the current Instructions have been setup to do
> simulation yes, and look at the comment in prepareStep() to see what is
> needed to fully enable this option) or reset the current Instruction
> (removing the breakpoint instruction temporarily). Accordingly a
> Breakpoint can be in the state NOT_STEPPING, OUT_OF_LINE_STEPPING,
> SIMULATE_STEPPING or RESET_STEPPING.
>
> In the case of RESET_STEPPING (which was the only option we supported
> before) other Tasks might miss and just past the Breakpoint during the
> brief period between the reset, step and reinstall. Breakpoint
> prepareStep() just takes the Instruction bytes and puts them at the
> current pc address, and doneStep() reinstates the breakpoint
> instruction.
>
> When the Instruction supports single step out of line then the
> Breakpoint requests an address in the single step out of line area of
> the Proc, instructs the Instruction to install itself there for the
> current Task calling Instruction.setupExecuteOutOfLine(). The default
> action of setupExecuteOutOfLine() is to set the pc to the given address
> and place a copy the instruction bytes there (although this can be
> overridden if an Instruction wants to do something more fancy). When the
> task signals the Breakpoint that a step was taken by calling stepDone(),
> the Breakpoint calls Instruction fixupExecuteOutOfLine() with the
> original pc and replacement address so any adjustments can be done to
> the Task registers. The default action is to just set the pc to the
> original pc plus the length of the Instruction just stepped. But
> Instructions can override that if more is needed. As an example the RET
> instruction doesn't do any fixup (since the only action is setting the
> pc to the right location in the first place) and the JMP instruction
> sets the pc to original pc plus/minus the difference of the alternate
> address and the pc after the single step. Afterward the Breakpoint
> returns the used address to the Proc so it can be used by other Tasks
> needing to do a single step out of line.
>
> The Proc maintains a single step out of line area pool of addresses that
> point to locations that are at least as big is the largest instruction
> of the instruction set. The Proc gets this list from the Isa the first
> time an address is requested through getOutOfLineAddress(). Currently
> this is (for x86 and x86_64) just the address of the main function entry
> point(see below). The address is taken out of the pool and the
> Breakpoint is responsible for putting it back through doneOutOfLine (see
> above). If no address is currently available the call blocks till one is
> available (this was way easier than inventing yet another TaskState and
> getting the communication between Proc and Task about this right, and
> contention is very low and at the longest it takes for an address to
> become available is one instruction single step).
>
> All the above seems to work nicely for x86 and x86_64 (powerpc hasn't
> been updated, but as long as an Isa doesn't return Instructions through
> an instruction parser that returns single stepping out of line capable
> Instructions the old reset-breakpoint stepping is used) with all the old
> testcases and a couple of new ones but there are 3 areas of improvement
> needed:
>
> - Instruction Parser.  The framework is in place and works for the few
> Instructions that are known to the instruction parse, but there are all
> hand coded (see IA32InstructionParser which just handles NOP, INT3, RETQ
> and one JMP variant, the X8664Instruction just delegates to the IA32 for
> now). There don't seem to be libraries available to easily plugin that
> would give us the fixup instructions needed. The best available is the
> kprobes examples from the linux kernel which have as drawback that they
> are coded to be intimately tied to the kernel/C way of doing things and
> only handles instructions found in kernel space. For uprobes this should
> have been extended to handle every instruction that can occur in user
> space, but I haven't seen that work yet (and apparently is only
> available for x86 and no other architecture at this time). Any
> alternatives to look at would be appreciated. Otherwise I need to sit
> down with the various instruction manuals and just code it up by hand.
> (Bonus points for finding something that would not just give us ssol
> fixups but also simulation of instructions when hooked to the registers
> and memory of a Task).
>
> - Testsuite.  The best I could come up with for now is TestInstructions
> and funit-instructions.c which is a nice little framework for having a
> simple assembly instructions labeled in such a way that a 'instruction
> address path' can be communicated to the java side so it can do either a
> full step through the program or install breakpoints on every
> instruction and make sure that every step and/or breakpoint hit takes it
> to the right next address. But the assembly part has to be written
> completely by hand (and unsurprisingly the simple assembly program
> currently used works identically on x86 and x86_64). Trying to reuse the
> funit-asm.h generic assembly instructions to make it platform neutral
> was really hard especially since the labels used on the C and inline
> assembly side have to kept in sync and mixing C defines and asm
> statements don't seem to mix very well. Also at the moment it is just
> using nops and jmps to keep things simple. I guess that in the end, if
> we have real instruction parsers we could try to generate them using
> that. Ideas or experiences with setting something up to track individual
> instructions and getting the right addresses listed appreciated.
>
> - Single Step Out Of Line Address Area.  Currently the Isa (for x86 and
> x86_64 at least) just provide one address. The address of the main()
> function entry point taken by just doing:
>
>         Elf elf = new Elf(proc.getExe(), ElfCommand.ELF_C_READ);
>         Dwarf dwarf = new Dwarf(elf, DwarfCommand.READ, null);
>         DwarfDie die = DwarfDie.getDecl(dwarf, "main");
>         return die.getEntryBreakpoints();
>
> This works surprisingly well for a simple first approach, and programs
> generally don't reenter their own main() function. But it would be nice
> to either find an area that is guaranteed to never be used (again) by
> the process, or to map in an executable area in the inferior that is
> just used by us (maybe just making the inferior load a dummy shared
> library). Again any suggestions welcome.
>   

  parent reply	other threads:[~2007-07-05 18:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-04 18:20 Mark Wielaard
2007-07-05  4:45 ` Phil Muldoon
2007-07-05 12:39   ` Mark Wielaard
2007-07-10  9:59     ` Leaving visible breakpoints in memory/core (Was: Breakpoint stepping) Mark Wielaard
2007-07-10 13:52       ` Andrew Cagney
2007-07-10 18:06       ` Phil Muldoon
2007-07-11  9:47         ` Mark Wielaard
2007-07-12  2:49           ` Roland McGrath
2007-07-12 14:24             ` Phil Muldoon
2007-07-12 20:24               ` Roland McGrath
2007-07-16 15:57                 ` Mark Wielaard
2007-07-17 15:43                   ` Phil Muldoon
2007-07-17 17:06                     ` Mark Wielaard
2007-07-16 15:53               ` Mark Wielaard
2007-07-17 15:47                 ` Phil Muldoon
2007-07-17 17:08                   ` Mark Wielaard
2007-07-05 18:37 ` Andrew Cagney [this message]
2007-07-23 12:19   ` Breakpoint stepping Mark Wielaard
2007-07-10 10:39 ` Instruction parser (Was: Breakpoint stepping) Mark Wielaard
2007-07-10 10:50 ` Instruction breakpoint-stepping testsuite " Mark Wielaard
2007-07-16  9:19   ` [patch] " Mark Wielaard
2007-07-10 10:57 ` SSOL Area " Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=468D3A87.4020205@redhat.com \
    --to=cagney@redhat.com \
    --cc=frysk@sourceware.org \
    --cc=mark@klomp.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).