This is the mail archive of the frysk@sourceware.org mailing list for the frysk 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


Hi,

Mike asked for a quick rundown how low-level stepping worked at the
moment and I thought it would be a good idea to CC the mailinglist with
my answer so it is in the archives (and others can point at it and make
fun of any design mistakes).

I am currently desperately (still trying to get all tests working again)
trying to get my new low-level breakpoint-stepping code in. It
introduces 2 low-level ways of doing breakpoint-stepping, but I think
the code is a little cleaner since it is easier to separate the state
machine from the underlying stepping mechanism used. I'll write a bit
more about it when that is finally in. The following is how it happens
at this time:

Lets assume (since that was actually what Mike asked) that we installed
an InstructionObserver, the Task stopped notified the observer which
decided that the Task needed to be blocked which turned the TaskState
into BlockedSignal. If you are interested in what would happen while
stepping and the Task not being blocked already, start reading from (*)
and assume we are in the Running state and just want to continue running
the task after some event happened.

So we start at Task.unblock(InstructionObserver) look at
frysk/proc/ptrace/LinuxTaskState.java (around line 1212) the
BlockedSignal class. The handleUnblock() method will be triggered.
Depending on which observers are actually installed (and whether all
blocking observer have been cleared now) a Running TaskState is
determined and sendContinue(task, sig) is called on that Running state
(also in the same java source file, see around line 725).

(*) We are interested in the following line in sendContinue():

  // Step when there is a breakpoint at the current location            
  // or there are Instruction observers installed.                      
  if (bp != null
      || task.instructionObservers.numberOfObservers() > 0)
    task.sendStepInstruction(sig);

The instance of sendStepInstruction() that we call here is defined in
frysk/proc/ptrace/LinuxTask.java (around line 250). This will do some
bookkeeping to remember that a step instruction was requested, which
signal number was requested and whether or not the Task is currently at
a signal return instruction. We need to do that here so we know what we
were doing when we get a callback from the kernel after the step. Then
the appropriate ptrace command is invoked so the Task is doing the
actual step.

If the Task made its step then we will get a TrappedEvent. We are in a
Running state so see LinuxTaskState.java again at line 930. Here things
get a little messy since ptrace/wait uses trap events for signaling
almost everything. Luckily the Isa should be able to tell us if the
current Task just did an instruction step. If it did (and it isn't a
breakpoint address in which case we need to do some extra things) then
we inform all InstructionObservers and if any of them tells us to Block
then we move into the BlockedSignal state, otherwise we keep in the
Running state and continue from (*).

Hope this helps. I'll send an update about the handwavy
breakpoint-stepping case above soon after my code hits cvs.

Cheers,

mark

Attachment: signature.asc
Description: This is a digitally signed message part


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