public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* Re: [SCM]  master: Add stepping and running Watchpoint tests.
       [not found] <20080409142101.16770.qmail@sourceware.org>
@ 2008-04-09 16:33 ` Phil Muldoon
  0 siblings, 0 replies; only message in thread
From: Phil Muldoon @ 2008-04-09 16:33 UTC (permalink / raw)
  To: frysk

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 <pmuldoon@redhat.com>
> Date:   Wed Apr 9 15:18:35 2008 +0100
>
>     Add stepping and running Watchpoint tests.
>     
>     2008-04-09  Phil Muldoon  <pmuldoon@redhat.com>
>     
>     	* TestTaskObserverWatchpoint.java: New.
>     	(testSteppingInstructionAndWatchpoint): New test.
>     	(testRunningAndWatchpoint): Moved and rewritten
>     	from -> isa/watchpoints/TestWatchpoint. testWatchpointTrigger.
>     
>     2008-04-09  Phil Muldoon  <pmuldoon@redhat.com>
>     
>     	* TestWatchpoint.java (testWatchpointTrigger): Move
>     	to frysk/proc/TestTaskObserverWatchpoint.
>
> commit 6886bffba783f49f531ac8608bafa90ab71b3fc1
> Author: Phil Muldoon <pmuldoon@redhat.com>
> Date:   Wed Apr 9 15:15:12 2008 +0100
>
>     Add stepping and running watchpoint state testcases.
>     
>     2008-04-09  Phil Muldoon  <pmuldoon@redhat.com>
>     
>             * TestWatchpoint.java (testWatchpointTrigger): Move
>             to frysk/proc/TestTaskObserverWatchpoint.
>     
>     2008-04-09  Phil Muldoon  <pmuldoon@redhat.com>
>     
>             * 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  <pmuldoon@redhat.com>
> +
> +	* TestWatchpoint.java (testWatchpointTrigger): Move
> +	to frysk/proc/TestTaskObserverWatchpoint.
> +
>  2008-04-07  Phil Muldoon  <pmuldoon@redhat.com>
>  
>  	* 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  <mwielaard@redhat.com>
> +2008-04-09  Phil Muldoon  <pmuldoon@redhat.com>
> +
> +	* TestTaskObserverWatchpoint.java: New.
> +	(testSteppingInstructionAndWatchpoint): New test.
> +	(testRunningAndWatchpoint): Moved and rewritten
> +	from -> isa/watchpoints/TestWatchpoint. testWatchpointTrigger.
>  
> +2008-04-09  Mark Wielaard  <mwielaard@redhat.com>
>  	* 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
>   

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-04-09 14:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20080409142101.16770.qmail@sourceware.org>
2008-04-09 16:33 ` [SCM] master: Add stepping and running Watchpoint tests Phil Muldoon

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).