* patch to add breakpoint commands
@ 2008-03-05 16:39 Tom Tromey
2008-03-05 17:42 ` Andrew Cagney
0 siblings, 1 reply; 3+ messages in thread
From: Tom Tromey @ 2008-03-05 16:39 UTC (permalink / raw)
To: frysk
Here's a patch that adds breakpoint commands. I recommend not
committing it, because it is ugly, but I thought I'd post it so folks
can see what needs to be done.
Problems with this:
* I really wanted to give commands a "-silent" option (I never liked
gdb's "'silent' is a magical first command" thing) -- but doing this
would mean hooking into BreakpointCommand.
* We need a new command to show all the commands. I guess plain
"commands" could do it. Really, though, I think "actions" should do
it (a la "info b" in gdb)...
* Also notice the WeakReference stuff. I guess other choices for
doing the memory management would have worked ok. Personally I
would probably just refactor SourceBreakpoint, or make a new
subclass used by all standard fhpd commands, and put a lot of stuff
into that -- silence -vs- announcing the breakpoint, commands,
conditions.
* CLI is strangely factored... it holds the prompt but only fhpd.java
uses it. I don't really follow the design here. Ideally (for
"commands") CLI should be re-entrant...
* Related to that, "commands" doesn't know about itself, so the first
"end" will terminate the commands, even if you try to nest them.
* There is some cut-and-paste code in CommandsCommand, mostly taken
from ActionPointCommands, which has its own share of cut-and-paste
and weird stuff.
Really this is 4th or 5th on my must-have list. More important would
be breakpoint conditions. Or annotations -- but I wanted to get my
feet wet with something simpler first.
Tom
diff --git a/frysk-core/frysk/hpd/CLI.java b/frysk-core/frysk/hpd/CLI.java
index f8f16c8..dbe3243 100644
--- a/frysk-core/frysk/hpd/CLI.java
+++ b/frysk-core/frysk/hpd/CLI.java
@@ -192,7 +192,7 @@ public class CLI {
final PrintWriter outWriter;
private Preprocessor prepro;
private String prompt; // string to represent prompt, will be moved
- private final Command topLevelCommand = new TopLevelCommand();
+ final Command topLevelCommand = new TopLevelCommand();
final DbgVariables dbgvars = new DbgVariables();
// PT set related stuff
@@ -209,6 +209,11 @@ public class CLI {
// alias
final HashMap aliases;
+ // When evaluating a command, this holds an iterator of the
+ // following commands on the line. Usually this should only be
+ // used by commands which themselves read and store commands.
+ Iterator inputIterator;
+
/*
* Public methods
*/
@@ -277,8 +282,9 @@ public class CLI {
// NULL when EOF.
try {
// preprocess and iterate
- for (Iterator iter = prepro.preprocess(cmd); iter.hasNext();) {
- String pcmd = (String)iter.next();
+ inputIterator = prepro.preprocess(cmd);
+ while (inputIterator.hasNext()) {
+ String pcmd = (String)inputIterator.next();
Input command = new Input(pcmd);
// Ignore empty commands
if (command.size() > 0)
@@ -287,6 +293,7 @@ public class CLI {
} catch (RuntimeException e) {
printError(e);
}
+ inputIterator = null;
}
flushMessages();
return null;
diff --git a/frysk-core/frysk/hpd/CommandsCommand.java b/frysk-core/frysk/hpd/CommandsCommand.java
new file mode 100644
index 0000000..a7bcba6
--- /dev/null
+++ b/frysk-core/frysk/hpd/CommandsCommand.java
@@ -0,0 +1,209 @@
+// 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.hpd;
+
+import frysk.rt.SourceBreakpointObserver;
+import frysk.rt.SourceBreakpoint;
+import frysk.rt.BreakpointManager;
+import frysk.proc.Task;
+import frysk.util.ObservingTerminal;
+import frysk.sys.FileDescriptor;
+
+import jline.ConsoleReader;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+public class CommandsCommand extends ParameterizedCommand {
+ private static class Options {
+ boolean delete;
+ }
+
+ Object options() {
+ return new Options();
+ }
+
+ private static class CommandsObserver implements SourceBreakpointObserver {
+ private CLI cli;
+ private List commands;
+
+ public CommandsObserver(CLI cli, List commands) {
+ this.cli = cli;
+ this.commands = commands;
+ }
+
+ public void updateHit(SourceBreakpoint breakpoint, Task task,
+ long address) {
+ Iterator i = commands.iterator();
+ while (i.hasNext()) {
+ Input cmd = (Input) i.next();
+ cli.topLevelCommand.interpret(cli, cmd);
+ }
+ }
+
+ public void addedTo(Object o) { }
+ public void addFailed(Object o, Throwable t) { }
+ public void deletedFrom(Object o) { }
+ }
+
+ // FIXME: super lame.
+ private WeakReference[] allCommands;
+
+ CommandsCommand() {
+ // FIXME: we'd like to support '-silent', like gdb's "silent", but
+ // that actually requires changes in BreakpointCommand.
+ super("Set or modify commands for an action point",
+ "commands ACTIONPOINT-ID",
+ "Set or delete the commands attached to an action point. "
+ + "With -delete, the command list is deleted. "
+ + "Otherwise, commands are read until \"end\".");
+ add(new CommandOption("delete", "Delete commands for action point") {
+ void parse(String arg, Object options) {
+ ((Options) options).delete = true;
+ }
+ });
+ }
+
+ // Add strings from the iterator to the list.
+ // If we see "end", return true.
+ // Otherwise add all the strings and return false.
+ private boolean addFromIterator(Iterator iter, List result) {
+ while (iter.hasNext()) {
+ String cmd = (String) iter.next();
+ if (cmd.equals("end"))
+ return true;
+ result.add(new Input(cmd));
+ }
+ return false;
+ }
+
+ private List readCommands(CLI cli) {
+ List result = new ArrayList();
+ // Perhaps there were other commands on the same command line.
+ if (cli.inputIterator != null) {
+ if (addFromIterator(cli.inputIterator, result))
+ return result;
+ }
+ // Read more commands from the user.
+ // FIXME: should be able to use the same reader as the
+ // top-level, but this is not available anywhere.
+ try {
+ ConsoleReader reader = new ConsoleReader
+ (new FileInputStream(java.io.FileDescriptor.in),
+ new PrintWriter(System.out),
+ null,
+ new ObservingTerminal(FileDescriptor.in));
+ Preprocessor prep = new Preprocessor();
+
+ while (true) {
+ String line = reader.readLine("> ");
+ if (line != null) {
+ if (addFromIterator(prep.preprocess(line), result)) {
+ return result;
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ void interpret(CLI cli, Input input, Object opts) {
+ if (input.size() == 0) {
+ throw new InvalidCommandException("missing actionpoint argument");
+ } else if (input.size() != 1) {
+ throw new InvalidCommandException("too many arguments");
+ }
+
+ // Cut and paste from ActionPointCommands.
+ String[] points = input.stringValue().split(",");
+ int[] ids = new int[points.length];
+ for (int i = 0; i < points.length; i++)
+ try {
+ ids[i] = Integer.parseInt(points[i]);
+ } catch (NumberFormatException e) {
+ throw new InvalidCommandException
+ ("Invalid actionpoint id " + points[i]);
+ }
+
+ Options options = (Options) opts;
+ List commands = null;
+ if (!options.delete)
+ commands = readCommands(cli);
+
+ BreakpointManager bpManager = cli.getSteppingEngine()
+ .getBreakpointManager();
+ Iterator iterator = bpManager.getBreakpointTableIterator();
+ while (iterator.hasNext()) {
+ SourceBreakpoint bpt = (SourceBreakpoint) iterator.next();
+ int id = bpt.getId();
+ if (Arrays.binarySearch(ids, id) < 0)
+ continue;
+ if (options.delete) {
+ if (allCommands == null || id >= allCommands.length
+ || allCommands[id].get() == null)
+ continue;
+ bpt.deleteObserver((CommandsObserver) allCommands[id].get());
+ } else {
+ if (allCommands == null) {
+ allCommands = new WeakReference[20];
+ } else if (allCommands.length <= id) {
+ WeakReference[] newCommands = new WeakReference[id];
+ System.arraycopy(newCommands, 0, allCommands, 0,
+ allCommands.length);
+ allCommands = newCommands;
+ }
+ CommandsObserver ob = new CommandsObserver(cli, commands);
+ bpt.addObserver(ob);
+ allCommands[id] = new WeakReference(ob);
+ }
+ }
+ }
+
+ int completer(CLI cli, Input input, int cursor, List candidates) {
+ return -1;
+ }
+}
diff --git a/frysk-core/frysk/hpd/TopLevelCommand.java b/frysk-core/frysk/hpd/TopLevelCommand.java
index d6d14bc..81e1d81 100644
--- a/frysk-core/frysk/hpd/TopLevelCommand.java
+++ b/frysk-core/frysk/hpd/TopLevelCommand.java
@@ -1,6 +1,6 @@
// This file is part of the program FRYSK.
//
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007, 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
@@ -119,5 +119,6 @@ public class TopLevelCommand extends MultiLevelCommand {
add(new ViewsetCommand(), "viewset");
add(new DefsetCommand(), "defset");
add(new UndefsetCommand(), "undefset");
+ add(new CommandsCommand(), "commands");
}
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: patch to add breakpoint commands
2008-03-05 16:39 patch to add breakpoint commands Tom Tromey
@ 2008-03-05 17:42 ` Andrew Cagney
2008-03-05 18:03 ` Tom Tromey
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Cagney @ 2008-03-05 17:42 UTC (permalink / raw)
To: Tom Tromey; +Cc: frysk
Tom Tromey wrote:
> Here's a patch that adds breakpoint commands. I recommend not
> committing it, because it is ugly, but I thought I'd post it so folks
> can see what needs to be done.
>
> Problems with this:
>
> * I really wanted to give commands a "-silent" option (I never liked
> gdb's "'silent' is a magical first command" thing) -- but doing this
> would mean hooking into BreakpointCommand.
>
I have to agree; hpd describes this entire group as "actionpoints" and
lists:
- breakpoints
- watchpoints
- barrier
and we've suggestions for additions such as:
- catch syscall
- catch dlopen (?)
- catch signal
- catch fork
- catch clone
- catch exec
for all of these they have several things:
- the commands to run when the event is triggered
- should the hit be verbose or silent
- should the end result be to stop or continue (attribute or not?)
- ?
that can be characterised as attributes; as, dare I suggest, you're
reading into the intent of the HPD, the way to do this is would be with
-silent option to the commands that create and edit (see actions)
actionpoints.
Andrew
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: patch to add breakpoint commands
2008-03-05 17:42 ` Andrew Cagney
@ 2008-03-05 18:03 ` Tom Tromey
0 siblings, 0 replies; 3+ messages in thread
From: Tom Tromey @ 2008-03-05 18:03 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Tom Tromey, frysk
Andrew> for all of these they have several things:
[...]
Andrew> - should the end result be to stop or continue (attribute or not?)
For this I don't see much wrong with the gdb model -- stop by default,
let the command specify "go" if it wants. This has never caused me
much trouble (while OTOH I frequently forget 'silent').
Andrew> that can be characterised as attributes; as, dare I suggest,
Andrew> you're reading into the intent of the HPD, the way to do this
Andrew> is would be with -silent option to the commands that create
Andrew> and edit (see actions) actionpoints.
Yeah, that would be fine by me.
Tom
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-03-05 18:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-05 16:39 patch to add breakpoint commands Tom Tromey
2008-03-05 17:42 ` Andrew Cagney
2008-03-05 18:03 ` Tom Tromey
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).