From: Phil Muldoon <pmuldoon@redhat.com>
To: frysk@sourceware.org
Subject: Re: [SCM] master: Add stepping and running Watchpoint tests.
Date: Wed, 09 Apr 2008 16:33:00 -0000 [thread overview]
Message-ID: <47FCD1E1.80203@redhat.com> (raw)
In-Reply-To: <20080409142101.16770.qmail@sourceware.org>
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
>
parent reply other threads:[~2008-04-09 14:26 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <20080409142101.16770.qmail@sourceware.org>]
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=47FCD1E1.80203@redhat.com \
--to=pmuldoon@redhat.com \
--cc=frysk@sourceware.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).