1 /*
   2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package lib.jdb;
  25 
  26 import java.util.Arrays;
  27 import java.util.regex.Pattern;
  28 import java.util.stream.Collectors;
  29 
  30 /**
  31  * Represents list of commands of <code>jdb</code> from JDK1.4:
  32  *
  33  *   run [class [args]]        -- start execution of application's main class
  34  *
  35  *   threads [threadgroup]     -- list threads
  36  *   thread <thread id>        -- set default thread
  37  *   suspend [thread id(s)]    -- suspend threads (default: all)
  38  *   resume [thread id(s)]     -- resume threads (default: all)
  39  *   where [thread id] | all   -- dump a thread's stack
  40  *   wherei [thread id] | all  -- dump a thread's stack, with pc info
  41  *   up [n frames]             -- move up a thread's stack
  42  *   down [n frames]           -- move down a thread's stack
  43  *   kill <thread> <expr>      -- kill a thread with the given exception object
  44  *   interrupt <thread>        -- interrupt a thread
  45  *
  46  *   print <expr>              -- print value of expression
  47  *   dump <expr>               -- print all object information
  48  *   eval <expr>               -- evaluate expression (same as print)
  49  *   set <lvalue> = <expr>     -- assign new value to field/variable/array element
  50  *   locals                    -- print all local variables in current stack frame
  51  *
  52  *   classes                   -- list currently known classes
  53  *   class <class id>          -- show details of named class
  54  *   methods <class id>        -- list a class's methods
  55  *   fields <class id>         -- list a class's fields
  56  *
  57  *   threadgroups              -- list threadgroups
  58  *   threadgroup <name>        -- set current threadgroup
  59  *
  60  *   stop in <class id>.<method>[(argument_type,...)]
  61  *                             -- set a breakpoint in a method
  62  *   stop at <class id>:<line> -- set a breakpoint at a line
  63  *   clear <class id>.<method>[(argument_type,...)]
  64  *                             -- clear a breakpoint in a method
  65  *   clear <class id>:<line>   -- clear a breakpoint at a line
  66  *   clear                     -- list breakpoints
  67  *   catch <class id>          -- break when specified exception thrown
  68  *   ignore <class id>         -- cancel 'catch'  for the specified exception
  69  *   watch [access|all] <class id>.<field name>
  70  *                             -- watch access/modifications to a field
  71  *   unwatch [access|all] <class id>.<field name>
  72  *                             -- discontinue watching access/modifications to a field
  73  *   trace methods [thread]    -- trace method entry and exit
  74  *   untrace methods [thread]  -- stop tracing method entry and exit
  75  *   step                      -- execute current line
  76  *   step up                   -- execute until the current method returns to its caller
  77  *   stepi                     -- execute current instruction
  78  *   next                      -- step one line (step OVER calls)
  79  *   cont                      -- continue execution from breakpoint
  80  *
  81  *   list [line number|method] -- print source code
  82  *   use (or sourcepath) [source file path]
  83  *                             -- display or change the source path
  84  *   exclude [class id ... | "none"]
  85  *                             -- do not report step or method events for specified classes
  86  *   classpath                 -- print classpath info from target VM
  87  *
  88  *   monitor <command>         -- execute command each time the program stops
  89  *   monitor                   -- list monitors
  90  *   unmonitor <monitor#>      -- delete a monitor
  91  *   read <filename>           -- read and execute a command file
  92  *
  93  *   lock <expr>               -- print lock info for an object
  94  *   threadlocks [thread id]   -- print lock info for a thread
  95  *
  96  *   pop                       -- pop the stack through and including the current frame
  97  *   reenter                   -- same as pop, but current frame is reentered
  98  *   redefine <class id> <class file name>
  99  *                             -- redefine the code for a class
 100  *
 101  *   disablegc <expr>          -- prevent garbage collection of an object
 102  *   enablegc <expr>           -- permit garbage collection of an object
 103  *
 104  *   !!                        -- repeat last command
 105  *   <n> <command>             -- repeat command n times
 106  *   help (or ?)               -- list commands
 107  *   version                   -- print version information
 108  *   exit (or quit)            -- exit debugger
 109  *
 110  *   <class id>: full class name with package qualifiers or a
 111  *   pattern with a leading or trailing wildcard ('*').
 112  *   <thread id>: thread number as reported in the 'threads' command
 113  *   <expr>: a Java(tm) Programming Language expression.
 114  *   Most common syntax is supported.
 115  *
 116  *   Startup commands can be placed in either "jdb.ini" or ".jdbrc"
 117  *   in user.home or user.dir
 118  */
 119 public class JdbCommand {
 120     final String cmd;
 121     boolean allowExit = false;
 122     // Default pattern to wait for command to complete
 123     Pattern waitForPattern = Jdb.PROMPT_REGEXP;
 124 
 125     public JdbCommand(String cmd) {
 126         this.cmd = cmd;
 127     }
 128 
 129     public JdbCommand allowExit() {
 130         allowExit = true;
 131         return this;
 132     }
 133 
 134     public JdbCommand waitForPrompt(String pattern, boolean isMultiline) {
 135         waitForPattern = Pattern.compile(pattern, isMultiline ? Pattern.MULTILINE : 0);
 136         return this;
 137     }
 138 
 139 
 140     public static JdbCommand run(String ... params) {
 141         return new JdbCommand("run " + Arrays.stream(params).collect(Collectors.joining(" ")));
 142     }
 143     public static JdbCommand cont() {
 144         return new JdbCommand("cont");
 145     }
 146     public static JdbCommand dump(String what) {
 147         return new JdbCommand("dump " + what);
 148     }
 149     public static JdbCommand quit() {
 150         // the command suppose jdb terminates
 151         return new JdbCommand("quit").allowExit();
 152     }
 153     public static JdbCommand stopAt(String targetClass, int lineNum) {
 154         return new JdbCommand("stop at " + targetClass + ":" + lineNum);
 155     }
 156     public static JdbCommand stopThreadAt(String targetClass, int lineNum) {
 157         return new JdbCommand("stop thread at " + targetClass + ":" + lineNum);
 158     }
 159     public static JdbCommand stopGoAt(String targetClass, int lineNum) {
 160         return new JdbCommand("stop go at " + targetClass + ":" + lineNum);
 161     }
 162     public static JdbCommand stopIn(String targetClass, String methodName) {
 163         return new JdbCommand("stop in " + targetClass + "." + methodName);
 164     }
 165     public static JdbCommand thread(int threadNumber) {
 166         return new JdbCommand("thread " + threadNumber);
 167     }
 168     // clear <class id>:<line>   -- clear a breakpoint at a line
 169     public static JdbCommand clear(String targetClass, int lineNum) {
 170         return new JdbCommand("clear " + targetClass + ":" + lineNum);
 171     }
 172 
 173     // exception type used by catch/ignore
 174     public enum ExType{
 175         uncaught,
 176         caught,
 177         all
 178     }
 179     public static JdbCommand catch_(String classId) {
 180         return new JdbCommand("catch " + classId);
 181     }
 182     public static JdbCommand catch_(ExType eType, String classId) {
 183         return catch_(eType.toString() + " " + classId);
 184     }
 185     public static JdbCommand ignore(String classId) {
 186         return new JdbCommand("ignore " + classId);
 187     }
 188     public static JdbCommand ignore(ExType eType, String classId) {
 189         return ignore(eType.toString() + " " + classId);
 190     }
 191 
 192     public static JdbCommand step() {
 193         return new JdbCommand("step");
 194     }
 195     public static JdbCommand stepUp() {
 196         return new JdbCommand("step up");
 197     }
 198     public static JdbCommand next() {
 199         return new JdbCommand("next");
 200     }
 201 
 202     // where [thread id] | all
 203     public static JdbCommand where(String threadId) {
 204         return new JdbCommand("where " + threadId);
 205     }
 206     public static JdbCommand eval(String expr) {
 207         return new JdbCommand("eval " + expr);
 208     }
 209     public static JdbCommand print(String expr) {
 210         return new JdbCommand("print " + expr);
 211     }
 212 
 213     public static JdbCommand locals() {
 214         return new JdbCommand("locals");
 215     }
 216 
 217     public static JdbCommand set(String lvalue, String expr) {
 218         return new JdbCommand("set " + lvalue + " = " + expr);
 219     }
 220 
 221     public static JdbCommand lock(String expr) {
 222         return new JdbCommand("lock " + expr);
 223     }
 224 
 225     public static JdbCommand methods(String classId) {
 226         return new JdbCommand("methods " + classId);
 227     }
 228 
 229     // trace [go] methods [thread]
 230     //                           -- trace method entries and exits.
 231     //                           -- All threads are suspended unless 'go' is specified
 232     // trace [go] method exit | exits [thread]
 233     //                           -- trace the current method's exit, or all methods' exits
 234     //                           -- All threads are suspended unless 'go' is specified
 235     // untrace [methods]         -- stop tracing method entrys and/or exits
 236     public static JdbCommand trace(boolean go, String  mode, Integer threadId) {
 237         return new JdbCommand(" trace"
 238                 + (go ? " go" : "")
 239                 + (mode != null ? " " + mode : "")
 240                 + (threadId != null ? " " + threadId.toString() : ""));
 241     }
 242     // prints trace status
 243     public static JdbCommand trace() {
 244         return trace(false, null, null);
 245     }
 246     public static JdbCommand traceMethods(boolean go, Integer threadId) {
 247         return trace(go, "methods", threadId);
 248     }
 249     public static JdbCommand traceMethodExit(boolean go, Integer threadId) {
 250         return trace(go, "method exit", threadId);
 251     }
 252     public static JdbCommand traceMethodExits(boolean go, Integer threadId) {
 253         return trace(go, "method exits", threadId);
 254     }
 255     public static JdbCommand untrace() {
 256         return new JdbCommand("untrace");
 257     }
 258 
 259     // watch [access|all] <class id>.<field name>
 260     public static JdbCommand watch(String classId, String fieldName) {
 261         return new JdbCommand("watch " + classId + "." + fieldName);
 262     }
 263 
 264     public static JdbCommand pop() {
 265         return new JdbCommand("pop");
 266     }
 267 
 268     public static JdbCommand redefine(String classId, String classFileName) {
 269         return new JdbCommand("redefine " + classId + " " + classFileName);
 270     }
 271 }