From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17100 invoked by alias); 4 Apr 2008 14:38:41 -0000 Received: (qmail 17074 invoked by uid 9514); 4 Apr 2008 14:38:40 -0000 Date: Fri, 04 Apr 2008 14:38:00 -0000 Message-ID: <20080404143840.17059.qmail@sourceware.org> From: pmuldoon@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Implement top level interfaces. Test primary test case in TestWatchpoint. Add two modifications two stepping.handleTrappedEvent and running.handleTrappedEvent. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 1e6a205bbcbe119523df8e4a569a9aa3c9aa29b3 X-Git-Newrev: dfa543f7189c681764596fc958a6d640a9558d46 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q2/txt/msg00044.txt.bz2 The branch, master has been updated via dfa543f7189c681764596fc958a6d640a9558d46 (commit) from 1e6a205bbcbe119523df8e4a569a9aa3c9aa29b3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit dfa543f7189c681764596fc958a6d640a9558d46 Author: Phil Muldoon Date: Fri Apr 4 15:37:31 2008 +0100 Implement top level interfaces. Test primary test case in TestWatchpoint. Add two modifications two stepping.handleTrappedEvent and running.handleTrappedEvent. 2008-04-04 Phil Muldoon * TestWatchpoint.java (testWatchpointTrigger): New. (WatchpointObserver): New. (TerminatedObserver): New. * WatchpointFunctionFactory.java (getWatchpointFunctions): Renamed from getWatchpoint. * TestWatchpoint: Update getWatchpoint -> getWatchpointFunctions. 2008-04-04 Phil Muldoon * LinuxPtraceProc.java (LinuxPtraceProc): Instatiate watchpoint address manager. (WatchpointAction): New. Install watchpoints. (requestAddWatchObserver): Implement. (requestDeleteWatchObserver): Ditto. * WatchpointAddresses.java (proc): Store a proc, not a task. (addWatchpoint): Take a length, and a write only flag. (removeWatchpoint): Ditto. (getWatchObservers): Ditto. (getWatchpoint): Ditto. * Watchpoint.java (Watchpoint): Take a task and a writeOnly flag. (create): Ditto (getLength): New. (isWriteOnly): New. (set): Actually set the watchpoint. (reset): Delete the watchpoint. * LinuxPtraceTaskState.java (Running.handleTrappedEvent): Add watchpoint catch/test. (Stepping.handleTrappedEvent): Ditto. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/isa/watchpoints/ChangeLog | 9 ++ .../frysk/isa/watchpoints/TestWatchpoint.java | 87 +++++++++++++++++- .../isa/watchpoints/WatchpointFunctionFactory.java | 2 +- frysk-core/frysk/proc/live/ChangeLog | 24 +++++- frysk-core/frysk/proc/live/LinuxPtraceProc.java | 93 ++++++++++++++++++-- .../frysk/proc/live/LinuxPtraceTaskState.java | 34 +++++++- frysk-core/frysk/proc/live/Watchpoint.java | 91 +++++++++++++------ .../frysk/proc/live/WatchpointAddresses.java | 40 ++++----- 8 files changed, 315 insertions(+), 65 deletions(-) First 500 lines of diff: diff --git a/frysk-core/frysk/isa/watchpoints/ChangeLog b/frysk-core/frysk/isa/watchpoints/ChangeLog index 33613b2..4d0e585 100644 --- a/frysk-core/frysk/isa/watchpoints/ChangeLog +++ b/frysk-core/frysk/isa/watchpoints/ChangeLog @@ -1,3 +1,12 @@ +2008-04-04 Phil Muldoon + + * TestWatchpoint.java (testWatchpointTrigger): New. + (WatchpointObserver): New. + (TerminatedObserver): New. + * WatchpointFunctionFactory.java (getWatchpointFunctions): Renamed from + getWatchpoint. + * TestWatchpoint: Update getWatchpoint -> getWatchpointFunctions. + 2008-04-03 Phil Muldoon * WatchpointFunctions.java (readStatusRegister): Declare. diff --git a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java index db52a10..b6f516b 100644 --- a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java +++ b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java @@ -51,13 +51,92 @@ import lib.dwfl.ElfSymbolVisibility; import lib.dwfl.SymbolBuilder; import frysk.config.Config; import frysk.dwfl.DwflCache; +import frysk.isa.signals.Signal; +import frysk.proc.Action; +import frysk.proc.Manager; import frysk.proc.Proc; import frysk.proc.Task; +import frysk.proc.TaskObserver; import frysk.testbed.DaemonBlockedAtEntry; import frysk.testbed.TestLib; + public class TestWatchpoint extends TestLib { + public void testWatchpointTrigger () { + if (unresolvedOnPPC(5991)) + return; + + DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry( + Config.getPkgLibFile("funit-watchpoint")); + assertNotNull(ackProc); + + Proc proc = ackProc.getMainTask().getProc(); + Task task = proc.getMainTask(); + long address = getGlobalSymbolAddress(task,"source"); + + WatchpointObserver wpo = new WatchpointObserver(address,4); + task.requestAddWatchObserver(wpo, address, 4, true); + assertRunUntilStop("Add Observer"); + TerminatedObserver terminated = new TerminatedObserver(); + task.requestAddTerminatedObserver(terminated); + assertRunUntilStop("Add Observer"); + ackProc.requestUnblock(); + assertRunUntilStop("Test"); + } + + static class WatchpointObserver + implements TaskObserver.Watch + { + + long address; + int length; + + WatchpointObserver(long address, int length) { + this.address = address; + this.length = length; + + } + public Action updateHit(Task task, long address, int length) { + assertEquals("Triggered watchpoint address matches expected", this.address, address); + assertEquals("Triggered watchpoint length matches expected", this.length, length); + return Action.CONTINUE; + } + + public void addFailed(Object observable, Throwable w) { + fail("TaskOberer.Watch failed to be added to te task"); + } + + public void addedTo(Object observable) { + Manager.eventLoop.requestStop(); + } + + public void deletedFrom(Object observable) { + } + + } + + static class TerminatedObserver + implements TaskObserver.Terminated + { + + public void addFailed(Object observable, Throwable w) { + } + + public void addedTo(Object observable) { + Manager.eventLoop.requestStop(); + } + + public void deletedFrom(Object observable) { + } + + public Action updateTerminated(Task task, Signal signal, int value) { + Manager.eventLoop.requestStop(); + return Action.CONTINUE; + } + + } + public void testWatchFourBytesBitPattern() { // Test Four byte bit pattern in a cumulative fasion // across all WP registers. Assume global exact and @@ -69,7 +148,7 @@ public class TestWatchpoint extends TestLib { Task task = proc.getMainTask(); long address = getGlobalSymbolAddress(task,"source"); long debugControlRegister; - WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA()); + WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA()); long savedDebugControlRegister = wp.readControlRegister(task); for (int i=0; i<4; i++) { @@ -122,7 +201,7 @@ public class TestWatchpoint extends TestLib { Task task = proc.getMainTask(); long address = getGlobalSymbolAddress(task,"source"); long debugControlRegister; - WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA()); + WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA()); long savedDebugControlRegister = wp.readControlRegister(task); for (int i=0; i<4; i++) { @@ -177,7 +256,7 @@ public class TestWatchpoint extends TestLib { Task task = proc.getMainTask(); long address = getGlobalSymbolAddress(task,"source"); long debugControlRegister; - WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA()); + WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA()); long savedDebugControlRegister = wp.readControlRegister(task); @@ -230,7 +309,7 @@ public class TestWatchpoint extends TestLib { Proc proc = giveMeABlockedProc(); Task task = proc.getMainTask(); long address = getGlobalSymbolAddress(task,"source"); - WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA()); + WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA()); for (int i=0; i + + * LinuxPtraceProc.java (LinuxPtraceProc): Instatiate watchpoint + address manager. + (WatchpointAction): New. Install watchpoints. + (requestAddWatchObserver): Implement. + (requestDeleteWatchObserver): Ditto. + * WatchpointAddresses.java (proc): Store a proc, not a task. + (addWatchpoint): Take a length, and a write only flag. + (removeWatchpoint): Ditto. + (getWatchObservers): Ditto. + (getWatchpoint): Ditto. + * Watchpoint.java (Watchpoint): Take a task and a writeOnly flag. + (create): Ditto + (getLength): New. + (isWriteOnly): New. + (set): Actually set the watchpoint. + (reset): Delete the watchpoint. + * LinuxPtraceTaskState.java (Running.handleTrappedEvent): Add watchpoint + catch/test. + (Stepping.handleTrappedEvent): Ditto. + 2008-04-02 Phil Muldoon * LinuxPtraceProc.java (requestAddWatchObserver): Add writeOnly flag. @@ -9,8 +31,6 @@ (WatchpointAction): Delete. (requestAddWatchObserver): Delete private function. (requestDeleteWatchObserver): Delete private function. - - 2008-03-31 Stan Cox diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProc.java b/frysk-core/frysk/proc/live/LinuxPtraceProc.java index 9f10c22..c4a6853 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceProc.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceProc.java @@ -86,6 +86,7 @@ public class LinuxPtraceProc extends LiveProc { this.newState = LinuxPtraceProcState.initial(false); this.stat = stat; this.breakpoints = new BreakpointAddresses(this); + this.watchpoints = new WatchpointAddresses(this); ((LinuxPtraceHost)host).addProc(this); } @@ -97,6 +98,7 @@ public class LinuxPtraceProc extends LiveProc { super(task, fork); this.newState = LinuxPtraceProcState.initial(true); this.breakpoints = new BreakpointAddresses(this); + this.watchpoints = new WatchpointAddresses(this); ((LinuxPtraceHost)getHost()).addProc(this); } @@ -617,27 +619,105 @@ public class LinuxPtraceProc extends LiveProc { /** - * (Internal) Tell the process to add the specified Code + * Class describing the action to take on the suspended Task + * before adding or deleting a Code observer. + */ + final class WatchpointAction implements Runnable { + private final TaskObserver.Watch watch; + + private final Task task; + + private final long address; + + private final int length; + + private final boolean writeOnly; + + private final boolean addition; + + WatchpointAction(TaskObserver.Watch watch, Task task, long address, + int length, boolean writeOnly, boolean addition) { + this.watch = watch; + this.task = task; + this.address = address; + this.addition = addition; + this.length = length; + this.writeOnly = writeOnly; + + } + + public void run() { + if (addition) { + boolean mustInstall = watchpoints.addWatchpoint(watch, task, address, length, writeOnly); + if (mustInstall) { + Watchpoint watchpoint; + watchpoint = Watchpoint.create(address, length, writeOnly, task); + watchpoint.install(task); + } + } else { + boolean mustRemove = watchpoints.removeWatchpoint(watch, task, address, length, writeOnly); + if (mustRemove) { + Watchpoint watchpoint; + watchpoint = Watchpoint.create(address, length, writeOnly, task); + watchpoint.remove(task); + } + } + } + } + + + /** + * (Internal) Tell the process to add the specified Watch * Observation, attaching to the process if necessary. Adds a * TaskCodeObservation to the eventloop which instructs the task - * to install the breakpoint if necessary. + * to install the watchpoint if necessary. */ - void requestAddWatchObserver(Task task, TaskObservable observable, + void requestAddWatchObserver(final Task task, TaskObservable observable, TaskObserver.Watch observer, final long address, final int length, - boolean writeOnly) { + final boolean writeOnly) { + fine.log(this, "requestAddWatchObserver"); + WatchpointAction wpa = new WatchpointAction(observer, task, address, length, writeOnly, true); + TaskObservation to; + to = new TaskObservation((LinuxPtraceTask) task, observable, observer, wpa, true) { + public void execute() { + handleAddObservation(this); + } + public boolean needsSuspendedAction() { + return watchpoints.getWatchObservers(task, address, length, writeOnly) == null; + } + }; + Manager.eventLoop.add(to); + + } /** * (Internal) Tell the process to delete the specified Code * Observation, detaching from the process if necessary. */ - void requestDeleteWatchObserver(Task task, TaskObservable observable, + void requestDeleteWatchObserver(final Task task, TaskObservable observable, TaskObserver.Watch observer, final long address, final int length, - boolean writeOnly) { + final boolean writeOnly) { + + fine.log(this, "requestDeleteWatchObserver"); + WatchpointAction wpa = new WatchpointAction(observer, task, address, length, writeOnly, false); + TaskObservation to; + to = new TaskObservation((LinuxPtraceTask)task, observable, observer, wpa, false) { + public void execute() { + newState = oldState().handleDeleteObservation(LinuxPtraceProc.this, this); + } + + public boolean needsSuspendedAction() { + return watchpoints.getWatchObservers(task, address, length, writeOnly).size() == 1; + } + }; + + Manager.eventLoop.add(to); + } /** @@ -756,6 +836,7 @@ public class LinuxPtraceProc extends LiveProc { * XXX: Should not be public. */ public final BreakpointAddresses breakpoints; + public final WatchpointAddresses watchpoints; // List of available addresses for out of line stepping. // Used a lock in getOutOfLineAddress() and doneOutOfLine(). diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java index 07c9bd5..c08ff72 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java @@ -41,6 +41,8 @@ package frysk.proc.live; import frysk.sys.SignalSet; import frysk.sys.proc.Status; +import frysk.isa.watchpoints.WatchpointFunctionFactory; +import frysk.isa.watchpoints.WatchpointFunctions; import frysk.proc.TaskObserver; import frysk.proc.Observer; import frysk.proc.Observable; @@ -942,9 +944,22 @@ abstract class LinuxPtraceTaskState extends State { LinuxPtraceTaskState handleTrappedEvent(LinuxPtraceTask task) { fine.log("handleTrappedEvent", task); + // First test if this is a watchpoint event. + WatchpointFunctions watchpointFunction = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA()); + for (int i=0; i 0"); } @@ -86,9 +89,9 @@ public class Watchpoint implements Comparable * host type. If a Breakpoint for this address and proc is already * installed that Breakpoint will be returned. */ - public static Watchpoint create(long address, int length, Task task) + public static Watchpoint create(long address, int length, boolean writeOnly, Task task) { - Watchpoint watchpoint = new Watchpoint(address, length, task); + Watchpoint watchpoint = new Watchpoint(address, length, writeOnly, task); // If possible return an existing installed breakpoint. synchronized (installedWatchpoints) @@ -105,6 +108,15 @@ public class Watchpoint implements Comparable return address; } + public int getLength() + { + return length; + } + + public boolean isWriteOnly() + { + return writeOnly; + } /** * Installs breakpoint. Caller must make sure there is no breakpoint set @@ -130,16 +142,28 @@ public class Watchpoint implements Comparable */ private void set(Task task) { -// ByteBuffer buffer = ((LinuxPtraceTask)task).getRawMemory(); -// Isa isa = ((LinuxPtraceTask)task).getIsaFIXME(); -// Instruction bpInstruction = isa.getBreakpointInstruction(); -// -// origInstruction = isa.getInstruction(buffer, address); -// -// // Put in the breakpoint. -// byte[] bs = bpInstruction.getBytes(); -// buffer.position(address); -// buffer.put(bs); + // XXX: Need a get empty watchpoint locator. It's a bit + // much for the set() to find the empty watchpoint. Also + // question the value of optimizing at this point. + int watchpointIndex = -1; + frysk.isa.watchpoints.WatchpointFunctions wpf = + frysk.isa.watchpoints.WatchpointFunctionFactory. + getWatchpointFunctions(task.getISA()); + ArrayList watchpointList = (ArrayList) wpf.getAllWatchpoints(task); + Iterator i = watchpointList.iterator(); + while (i.hasNext()) { + frysk.isa.watchpoints.Watchpoint emptyTest = + ((frysk.isa.watchpoints.Watchpoint)i.next()); + if (emptyTest.getAddress() == 0) { + watchpointIndex = emptyTest.getRegister(); + break; hooks/post-receive -- frysk system monitor/debugger