From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21734 invoked by alias); 9 Apr 2008 14:26:01 -0000 Received: (qmail 21663 invoked by uid 22791); 9 Apr 2008 14:25:58 -0000 X-Spam-Status: No, hits=-0.5 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_34,J_CHICKENPOX_44,J_CHICKENPOX_45,J_CHICKENPOX_46,J_CHICKENPOX_47,J_CHICKENPOX_66,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 09 Apr 2008 14:25:43 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m39EPfBI032422 for ; Wed, 9 Apr 2008 10:25:41 -0400 Received: from pobox-2.corp.redhat.com (pobox-2.corp.redhat.com [10.11.255.15]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m39EPedB014588 for ; Wed, 9 Apr 2008 10:25:40 -0400 Received: from localhost.localdomain (vpn-14-129.rdu.redhat.com [10.11.14.129]) by pobox-2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m39EPcVe022315 for ; Wed, 9 Apr 2008 10:25:38 -0400 Message-ID: <47FCD1E1.80203@redhat.com> Date: Wed, 09 Apr 2008 16:33:00 -0000 From: Phil Muldoon User-Agent: Thunderbird 2.0.0.12 (X11/20080226) MIME-Version: 1.0 To: frysk@sourceware.org Subject: Re: [SCM] master: Add stepping and running Watchpoint tests. References: <20080409142101.16770.qmail@sourceware.org> In-Reply-To: <20080409142101.16770.qmail@sourceware.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2008-q2/txt/msg00040.txt.bz2 pmuldoon@sourceware.org wrote: This commits add two cornerstone tests. The stepping test is new and tests that: - Watchpoints are triggered during stepping - The neither a step or a watchpoint is starved of its sigtrap The running test was refactored from an existing test; it tests watchpoints trigger when the task is in a running state. Both tests add a Terminated observer to catch task exit, without watchpoint triggering (an unexpected condition). Regards Phil > The branch, master has been updated > via c3396dca96bee93a27eefd44857c8556cdb9a499 (commit) > via 6886bffba783f49f531ac8608bafa90ab71b3fc1 (commit) > from a3efa3a7e09b2760484ce7e6b0d67e74b170e8bb (commit) > > Those revisions listed above that are new to this repository have > not appeared on any other notification email. > > - Log ----------------------------------------------------------------- > commit c3396dca96bee93a27eefd44857c8556cdb9a499 > Merge: 6886bffba783f49f531ac8608bafa90ab71b3fc1 a3efa3a7e09b2760484ce7e6b0d67e74b170e8bb > Author: Phil Muldoon > Date: Wed Apr 9 15:18:35 2008 +0100 > > Add stepping and running Watchpoint tests. > > 2008-04-09 Phil Muldoon > > * TestTaskObserverWatchpoint.java: New. > (testSteppingInstructionAndWatchpoint): New test. > (testRunningAndWatchpoint): Moved and rewritten > from -> isa/watchpoints/TestWatchpoint. testWatchpointTrigger. > > 2008-04-09 Phil Muldoon > > * TestWatchpoint.java (testWatchpointTrigger): Move > to frysk/proc/TestTaskObserverWatchpoint. > > commit 6886bffba783f49f531ac8608bafa90ab71b3fc1 > Author: Phil Muldoon > Date: Wed Apr 9 15:15:12 2008 +0100 > > Add stepping and running watchpoint state testcases. > > 2008-04-09 Phil Muldoon > > * TestWatchpoint.java (testWatchpointTrigger): Move > to frysk/proc/TestTaskObserverWatchpoint. > > 2008-04-09 Phil Muldoon > > * TestTaskObserverWatchpoint.java: New. > (testSteppingInstructionAndWatchpoint): New test. > (testRunningAndWatchpoint): Moved and rewritten > from -> isa/watchpoints/TestWatchpoint. testWatchpointTrigger. > > ----------------------------------------------------------------------- > > Summary of changes: > frysk-core/frysk/isa/watchpoints/ChangeLog | 5 + > .../frysk/isa/watchpoints/TestWatchpoint.java | 81 +----- > frysk-core/frysk/proc/ChangeLog | 8 +- > .../frysk/proc/TestTaskObserverWatchpoint.java | 355 ++++++++++++++++++++ > 4 files changed, 368 insertions(+), 81 deletions(-) > create mode 100644 frysk-core/frysk/proc/TestTaskObserverWatchpoint.java > > First 500 lines of diff: > diff --git a/frysk-core/frysk/isa/watchpoints/ChangeLog b/frysk-core/frysk/isa/watchpoints/ChangeLog > index b58ecff..be0d350 100644 > --- a/frysk-core/frysk/isa/watchpoints/ChangeLog > +++ b/frysk-core/frysk/isa/watchpoints/ChangeLog > @@ -1,3 +1,8 @@ > +2008-04-09 Phil Muldoon > + > + * TestWatchpoint.java (testWatchpointTrigger): Move > + to frysk/proc/TestTaskObserverWatchpoint. > + > 2008-04-07 Phil Muldoon > > * WatchpointFunctions.java (resetWatchpoint): New. > diff --git a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java > index b6f516b..93349b9 100644 > --- a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java > +++ b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java > @@ -51,92 +51,13 @@ 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 > diff --git a/frysk-core/frysk/proc/ChangeLog b/frysk-core/frysk/proc/ChangeLog > index eab7ef8..ee466c5 100644 > --- a/frysk-core/frysk/proc/ChangeLog > +++ b/frysk-core/frysk/proc/ChangeLog > @@ -1,5 +1,11 @@ > -2008-04-09 Mark Wielaard > +2008-04-09 Phil Muldoon > + > + * TestTaskObserverWatchpoint.java: New. > + (testSteppingInstructionAndWatchpoint): New test. > + (testRunningAndWatchpoint): Moved and rewritten > + from -> isa/watchpoints/TestWatchpoint. testWatchpointTrigger. > > +2008-04-09 Mark Wielaard > * TestTaskObserverInstruction (testFirstInstructionAtEntry): > New test. > > diff --git a/frysk-core/frysk/proc/TestTaskObserverWatchpoint.java b/frysk-core/frysk/proc/TestTaskObserverWatchpoint.java > new file mode 100644 > index 0000000..a3ff13d > --- /dev/null > +++ b/frysk-core/frysk/proc/TestTaskObserverWatchpoint.java > @@ -0,0 +1,355 @@ > +// This file is part of the program FRYSK. > +// > +// Copyright 2008, Red Hat Inc. > +// > +// FRYSK is free software; you can redistribute it and/or modify it > +// under the terms of the GNU General Public License as published by > +// the Free Software Foundation; version 2 of the License. > +// > +// FRYSK is distributed in the hope that it will be useful, but > +// WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +// General Public License for more details. > +// > +// You should have received a copy of the GNU General Public License > +// along with FRYSK; if not, write to the Free Software Foundation, > +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. > +// > +// In addition, as a special exception, Red Hat, Inc. gives You the > +// additional right to link the code of FRYSK with code not covered > +// under the GNU General Public License ("Non-GPL Code") and to > +// distribute linked combinations including the two, subject to the > +// limitations in this paragraph. Non-GPL Code permitted under this > +// exception must only link to the code of FRYSK through those well > +// defined interfaces identified in the file named EXCEPTION found in > +// the source code files (the "Approved Interfaces"). The files of > +// Non-GPL Code may instantiate templates or use macros or inline > +// functions from the Approved Interfaces without causing the > +// resulting work to be covered by the GNU General Public > +// License. Only Red Hat, Inc. may make changes or additions to the > +// list of Approved Interfaces. You must obey the GNU General Public > +// License in all respects for all of the FRYSK code and other code > +// used in conjunction with FRYSK except the Non-GPL Code covered by > +// this exception. If you modify this file, you may extend this > +// exception to your version of the file, but you are not obligated to > +// do so. If you do not wish to provide this exception without > +// modification, you must delete this exception statement from your > +// version and license this file solely under the GPL without > +// exception. > + > +package frysk.proc; > + > +import lib.dwfl.Dwfl; > +import lib.dwfl.DwflModule; > +import lib.dwfl.ElfSymbolBinding; > +import lib.dwfl.ElfSymbolType; > +import lib.dwfl.ElfSymbolVisibility; > +import lib.dwfl.SymbolBuilder; > +import frysk.config.Config; > +import frysk.dwfl.DwflCache; > +import frysk.isa.signals.Signal; > +import frysk.rsl.Log; > +import frysk.testbed.DaemonBlockedAtEntry; > +import frysk.testbed.TestLib; > + > +public class TestTaskObserverWatchpoint > +extends TestLib > +{ > + > + private static final Log fine = Log.fine(TestTaskObserverWatchpoint.class); > + > + public void testSteppingInstructionAndWatchpoint() > + { > + if (unresolvedOnPPC(5991)) > + return; > + > + // Create a blocked child. > + DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry( > + Config.getPkgLibFile("funit-watchpoint")); > + assertNotNull(ackProc); > + > + // Get Proc/Task. > + Proc proc = ackProc.getMainTask().getProc(); > + Task task = proc.getMainTask(); > + > + // Watch for any unexpected terminations of the child process. > + TerminatedObserver to = new TerminatedObserver(); > + task.requestAddTerminatedObserver(to); > + > + // Break at main > + long mainAddress = getGlobalSymbolAddress(task, "main"); > + CodeObserver co = new CodeObserver(); > + task.requestAddCodeObserver(co, mainAddress); > + ackProc.requestUnblock(); > + assertRunUntilStop("Run to main"); > + > + // Add a stepping observer. > + InstructionObserver instr = new InstructionObserver(task); > + task.requestAddInstructionObserver(instr); > + instr.setContinue(true); > + > + // Find Variable source for watch > + long address = getGlobalSymbolAddress(task,"source"); > + > + // Add watch observer > + WatchObserver watch = new WatchObserver(task, address, 4); > + task.requestAddWatchObserver(watch, address, 4, true); > + > + task.requestUnblock(co); > + assertRunUntilStop("Run and test watchpoint "); > + > + // Make sure it triggered. > + assertTrue("added", watch.added); > + assertEquals("hit code", 1, watch.hit); > + > + // Delete both observers. > + task.requestDeleteInstructionObserver(instr); > + task.requestDeleteCodeObserver(co, mainAddress); > + task.requestDeleteWatchObserver(watch, address, 4, true); > + runPending(); > + > + // Verify they were removed. > + assertTrue("deleted instr", instr.deleted); > + assertTrue("deleted watch", watch.deleted); > + assertTrue("deleted code", co.deleted); > + assertEquals("hit code", 1, watch.hit); > + > + } > + > + > + public void testRunningAndWatchpoint () { > + if (unresolvedOnPPC(5991)) > + return; > + > + DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry( > + Config.getPkgLibFile("funit-watchpoint")); > + assertNotNull(ackProc); > + > + // Get Proc/Task. > + Proc proc = ackProc.getMainTask().getProc(); > + Task task = proc.getMainTask(); > + > + // Watch for any unexpected terminations of the child process. > + TerminatedObserver to = new TerminatedObserver(); > + task.requestAddTerminatedObserver(to); > + > + // Break at main > + long mainAddress = getGlobalSymbolAddress(task, "main"); > + CodeObserver co = new CodeObserver(); > + task.requestAddCodeObserver(co, mainAddress); > + ackProc.requestUnblock(); > + assertRunUntilStop("Run to main"); > + > + // Find Variable source for watch > + long address = getGlobalSymbolAddress(task,"source"); > + > + // Add watch observer > + WatchObserver watch = new WatchObserver(task, address, 4); > + task.requestAddWatchObserver(watch, address, 4, true); > + > + task.requestUnblock(co); > + assertRunUntilStop("Run and test watchpoint "); > + > + // Make sure it triggered. > + assertTrue("added", watch.added); > + assertEquals("hit code", 1, watch.hit); > + > + // Delete both observers. > + task.requestDeleteCodeObserver(co, mainAddress); > + task.requestDeleteWatchObserver(watch, address, 4, true); > + runPending(); > + > + // Verify they were removed. > + assertTrue("deleted watch", watch.deleted); > + assertTrue("deleted code", co.deleted); > + assertEquals("hit code", 1, watch.hit); > + > + } > + > + // Base class for this tests observers. > + // Keeps track of added, deleted and hit counts. > + static abstract class TestObserver implements TaskObserver > + { > + boolean added; > + boolean deleted; > + > + int hit; > + > + public void addedTo(Object o) > + { > + added = true; > + } > + > + public void deletedFrom(Object o) > + { > + deleted = true; > + } > + > + public void addFailed (Object o, Throwable w) > + { > + fail("add to " + o + " failed, because " + w); > + } > + } > + > + // Code observer. Run to a point in the program (normally main) > + // then block > + static class CodeObserver extends TestObserver > + implements TaskObserver.Code { > + > + public Action updateHit(Task task, long address) { > + fine.log("Hit breakpoint at ", address); > + Manager.eventLoop.requestStop(); > + return Action.BLOCK; > + } > + > + } > + // Simple observer to alert when child process dies unexpectedly > + static class TerminatedObserver extends TestObserver > + implements TaskObserver.Terminated > + { > + // Shouldn't be triggered ever. > + public Action updateTerminated(Task task, Signal signal, int value) { > + Manager.eventLoop.requestStop(); > + fail(task + " terminated; signal=" + signal > + + " value=" + value); > + return null; // not reached > + } > + } > + > + > + // Instruction Observer to simulate stepping > + static class InstructionObserver > + extends TestObserver > + implements TaskObserver.Instruction > + { > + private final Task task; > + private boolean cont; > + > + long lastAddress; > + > + InstructionObserver(Task task) > + { > + this.task = task; > + } > + > + public Action updateExecuted(Task task) > + { > + > + fine.log("Executing instruction at ", task.getPC()); > + if (! task.equals(this.task)) > + throw new IllegalStateException("Wrong Task, given " + task > + + " not equals expected " > + + this.task); > + > + hit++; > + lastAddress = task.getPC(); > + > + if (cont) > + return Action.CONTINUE; > + else > + { > + Manager.eventLoop.requestStop(); > + return Action.BLOCK; > + } > + } > + > + public void setContinue(boolean cont) > + { > + this.cont = cont; > + } > + } > + > + // And watchpoint observer to block our process > + // when it (should) trigger. > + static class WatchObserver > + extends TestObserver > + implements TaskObserver.Watch > + { > + private final Task task; > + private final long address; > + private final long length; > + > + public WatchObserver(Task task, long address, int length) > + { > + this.task = task; > + this.address = address; > + this.length = length; > + } > + > + > + public Action updateHit(Task task, long address, int length) { > + fine.log("Hit watchpoint, addess ", address); > + if (! task.equals(this.task)) > + throw new IllegalStateException("Wrong Task, given " + task > + + " not equals expected " > + + this.task); > + if (address != this.address) > + throw new IllegalStateException("Wrong address, given " + address > + + " not equals expected " > + + this.address); > + > + if (length != this.length) > + throw new IllegalStateException("Wrong length, given " + length > + + " not equals expected " > + + this.length); > + > + hit++; > + Manager.eventLoop.requestStop(); > + return Action.BLOCK; > + } > + } > + > + /** > + * Returns the address of a global label by quering the the Proc > + * main Task's Dwlf. > + */ > + long getGlobalSymbolAddress(Task task, String label) { > + Dwfl dwfl = DwflCache.getDwfl(task); > + Symbol sym = Symbol.get(dwfl, label); > + return sym.getAddress(); > + } > + > + > + // Helper class since there there isn't a get symbol method in Dwfl, > + // so we need to wrap it all in a builder pattern. > + static class Symbol implements SymbolBuilder { > + private String name; > + private long address; > + > + private boolean found; > + > + private Symbol() { > + // properties get set in public static get() method. > + } > + > + static Symbol get(Dwfl dwfl, String name) { > + Symbol sym = new Symbol(); > + sym.name = name; > + DwflModule[] modules = dwfl.getModules(); > + for (int i = 0; i < modules.length && ! sym.found; i++) > + modules[i].getSymbolByName(name, sym); > + > + if (sym.found) > + return sym; > + else > + return null; > + } > + > + String getName() { > + return name; > + } > + > + long getAddress() { > + return address; > + } > + > + public void symbol(String name, long value, long size, ElfSymbolType type, > + ElfSymbolBinding bind, ElfSymbolVisibility visibility) { > + if (name.equals(this.name)) { > + this.address = value; > + this.found = true; > + } > + > + } > + } > +} > > > hooks/post-receive > -- > frysk system monitor/debugger >