Exemple #1
0
 /* attach to running target vm */
 private VirtualMachine attachTarget() {
   AttachingConnector attacher = (AttachingConnector) connector;
   try {
     return attacher.attach(connectorArgs);
   } catch (IOException ioe) {
     ioe.printStackTrace();
     MessageOutput.fatalError("Unable to attach to target VM.");
   } catch (IllegalConnectorArgumentsException icae) {
     icae.printStackTrace();
     MessageOutput.fatalError("Internal debugger error.");
   }
   return null; // Shuts up the compiler
 }
Exemple #2
0
 static void shutdown(String message) {
   if (connection != null) {
     try {
       connection.disposeVM();
     } catch (VMDisconnectedException e) {
       // Shutting down after the VM has gone away. This is
       // not an error, and we just ignore it.
     }
   }
   if (message != null) {
     MessageOutput.lnprint(message);
     MessageOutput.println();
   }
   System.exit(0);
 }
Exemple #3
0
  synchronized VirtualMachine open() {
    if (connector instanceof LaunchingConnector) {
      vm = launchTarget();
    } else if (connector instanceof AttachingConnector) {
      vm = attachTarget();
    } else if (connector instanceof ListeningConnector) {
      vm = listenTarget();
    } else {
      throw new InternalError(MessageOutput.format("Invalid connect type"));
    }
    vm.setDebugTraceMode(traceFlags);
    if (vm.canBeModified()) {
      setEventRequests(vm);
      resolveEventRequests();
    }
    /*
     * Now that the vm connection is open, fetch the debugee
     * classpath and set up a default sourcepath.
     * (Unless user supplied a sourcepath on the command line)
     * (Bug ID 4186582)
     */
    if (Env.getSourcePath().length() == 0) {
      if (vm instanceof PathSearchingVirtualMachine) {
        PathSearchingVirtualMachine psvm = (PathSearchingVirtualMachine) vm;
        Env.setSourcePath(psvm.classPath());
      } else {
        Env.setSourcePath(".");
      }
    }

    return vm;
  }
Exemple #4
0
 /* listen for connection from target vm */
 private VirtualMachine listenTarget() {
   ListeningConnector listener = (ListeningConnector) connector;
   try {
     String retAddress = listener.startListening(connectorArgs);
     MessageOutput.println("Listening at address:", retAddress);
     vm = listener.accept(connectorArgs);
     listener.stopListening(connectorArgs);
     return vm;
   } catch (IOException ioe) {
     ioe.printStackTrace();
     MessageOutput.fatalError("Unable to attach to target VM.");
   } catch (IllegalConnectorArgumentsException icae) {
     icae.printStackTrace();
     MessageOutput.fatalError("Internal debugger error.");
   }
   return null; // Shuts up the compiler
 }
Exemple #5
0
 private void dumpFailedLaunchInfo(Process process) {
   try {
     dumpStream(process.getErrorStream());
     dumpStream(process.getInputStream());
   } catch (IOException e) {
     MessageOutput.println("Unable to display process output:", e.getMessage());
   }
 }
Exemple #6
0
 /** Return a description of an object. */
 static String description(ObjectReference ref) {
   ReferenceType clazz = ref.referenceType();
   long id = ref.uniqueID();
   if (clazz == null) {
     return toHex(id);
   } else {
     return MessageOutput.format(
         "object description and hex id", new Object[] {clazz.name(), toHex(id)});
   }
 }
  static void removeThread(ThreadReference thread) {
    if (thread.equals(ThreadInfo.current)) {
      // Current thread has died.

      // Be careful getting the thread name. If its death happens
      // as part of VM termination, it may be too late to get the
      // information, and an exception will be thrown.
      String currentThreadName;
      try {
        currentThreadName = "\"" + thread.name() + "\"";
      } catch (Exception e) {
        currentThreadName = "";
      }

      setCurrentThread(null);

      MessageOutput.println();
      MessageOutput.println("Current thread died. Execution continuing...", currentThreadName);
    }
    threads.remove(getThreadInfo(thread));
  }
Exemple #8
0
 /* launch child target vm */
 private VirtualMachine launchTarget() {
   LaunchingConnector launcher = (LaunchingConnector) connector;
   try {
     VirtualMachine vm = launcher.launch(connectorArgs);
     process = vm.process();
     displayRemoteOutput(process.getErrorStream());
     displayRemoteOutput(process.getInputStream());
     return vm;
   } catch (IOException ioe) {
     ioe.printStackTrace();
     MessageOutput.fatalError("Unable to launch target VM.");
   } catch (IllegalConnectorArgumentsException icae) {
     icae.printStackTrace();
     MessageOutput.fatalError("Internal debugger error.");
   } catch (VMStartException vmse) {
     MessageOutput.println("vmstartexception", vmse.getMessage());
     MessageOutput.println();
     dumpFailedLaunchInfo(vmse.process());
     MessageOutput.fatalError("Target VM failed to initialize.");
   }
   return null; // Shuts up the compiler
 }
Exemple #9
0
 private void dumpStream(InputStream stream) throws IOException {
   BufferedReader in = new BufferedReader(new InputStreamReader(stream));
   int i;
   try {
     while ((i = in.read()) != -1) {
       MessageOutput.printDirect((char) i); // Special case: use
       //   printDirect()
     }
   } catch (IOException ex) {
     String s = ex.getMessage();
     if (!s.startsWith("Bad file number")) {
       throw ex;
     }
     // else we got a Bad file number IOException which just means
     // that the debuggee has gone away.  We'll just treat it the
     // same as if we got an EOF.
   }
 }
Exemple #10
0
  VMConnection(String connectSpec, int traceFlags) {
    String nameString;
    String argString;
    int index = connectSpec.indexOf(':');
    if (index == -1) {
      nameString = connectSpec;
      argString = "";
    } else {
      nameString = connectSpec.substring(0, index);
      argString = connectSpec.substring(index + 1);
    }

    connector = findConnector(nameString);
    if (connector == null) {
      throw new IllegalArgumentException(MessageOutput.format("No connector named:", nameString));
    }

    connectorArgs = parseConnectorArgs(connector, argString);
    this.traceFlags = traceFlags;
  }
Exemple #11
0
  private Map<String, com.sun.jdi.connect.Connector.Argument> parseConnectorArgs(
      Connector connector, String argString) {
    Map<String, com.sun.jdi.connect.Connector.Argument> arguments = connector.defaultArguments();

    /*
     * We are parsing strings of the form:
     *    name1=value1,[name2=value2,...]
     * However, the value1...valuen substrings may contain
     * embedded comma(s), so make provision for quoting inside
     * the value substrings. (Bug ID 4285874)
     */
    String regexPattern =
        "(quote=[^,]+,)|"
            + // special case for quote=.,
            "(\\w+=)"
            + // name=
            "(((\"[^\"]*\")|"
            + //   ( "l , ue"
            "('[^']*')|"
            + //     'l , ue'
            "([^,'\"]+))+,)"; //     v a l u e )+ ,
    Pattern p = Pattern.compile(regexPattern);
    Matcher m = p.matcher(argString);
    while (m.find()) {
      int startPosition = m.start();
      int endPosition = m.end();
      if (startPosition > 0) {
        /*
         * It is an error if parsing skips over any part of argString.
         */
        throw new IllegalArgumentException(
            MessageOutput.format("Illegal connector argument", argString));
      }

      String token = argString.substring(startPosition, endPosition);
      int index = token.indexOf('=');
      String name = token.substring(0, index);
      String value = token.substring(index + 1, token.length() - 1); // Remove comma delimiter

      /*
       * for values enclosed in quotes (single and/or double quotes)
       * strip off enclosing quote chars
       * needed for quote enclosed delimited substrings
       */
      if (name.equals("options")) {
        StringBuilder sb = new StringBuilder();
        for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
          while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
            s = s.substring(1, s.length() - 1);
          }
          sb.append(s);
          sb.append(" ");
        }
        value = sb.toString();
      }

      Connector.Argument argument = arguments.get(name);
      if (argument == null) {
        throw new IllegalArgumentException(
            MessageOutput.format(
                "Argument is not defined for connector:", new Object[] {name, connector.name()}));
      }
      argument.setValue(value);

      argString = argString.substring(endPosition); // Remove what was just parsed...
      m = p.matcher(argString); //    and parse again on what is left.
    }
    if ((!argString.equals(",")) && (argString.length() > 0)) {
      /*
       * It is an error if any part of argString is left over,
       * unless it was empty to begin with.
       */
      throw new IllegalArgumentException(
          MessageOutput.format("Illegal connector argument", argString));
    }
    return arguments;
  }
Exemple #12
0
  private static List<String> splitStringAtNonEnclosedWhiteSpace(String value)
      throws IllegalArgumentException {
    List<String> al = new ArrayList<String>();
    char[] arr;
    int startPosition = 0;
    int endPosition = 0;
    final char SPACE = ' ';
    final char DOUBLEQ = '"';
    final char SINGLEQ = '\'';

    /*
     * An "open" or "active" enclosing state is where
     * the first valid start quote qualifier is found,
     * and there is a search in progress for the
     * relevant end matching quote
     *
     * enclosingTargetChar set to SPACE
     * is used to signal a non open enclosing state
     */
    char enclosingTargetChar = SPACE;

    if (value == null) {
      throw new IllegalArgumentException(MessageOutput.format("value string is null"));
    }

    // split parameter string into individual chars
    arr = value.toCharArray();

    for (int i = 0; i < arr.length; i++) {
      switch (arr[i]) {
        case SPACE:
          {
            // do nothing for spaces
            // unless last in array
            if (isLastChar(arr, i)) {
              endPosition = i;
              // break for substring creation
              break;
            }
            continue;
          }
        case DOUBLEQ:
        case SINGLEQ:
          {
            if (enclosingTargetChar == arr[i]) {
              // potential match to close open enclosing
              if (isNextCharWhitespace(arr, i)) {
                // if peek next is whitespace
                // then enclosing is a valid substring
                endPosition = i;
                // reset enclosing target char
                enclosingTargetChar = SPACE;
                // break for substring creation
                break;
              }
            }
            if (enclosingTargetChar == SPACE) {
              // no open enclosing state
              // handle as normal char
              if (isPreviousCharWhitespace(arr, i)) {
                startPosition = i;
                // peek forward for end candidates
                if (value.indexOf(arr[i], i + 1) >= 0) {
                  // set open enclosing state by
                  // setting up the target char
                  enclosingTargetChar = arr[i];
                } else {
                  // no more target chars left to match
                  // end enclosing, handle as normal char
                  if (isNextCharWhitespace(arr, i)) {
                    endPosition = i;
                    // break for substring creation
                    break;
                  }
                }
              }
            }
            continue;
          }
        default:
          {
            // normal non-space, non-" and non-' chars
            if (enclosingTargetChar == SPACE) {
              // no open enclosing state
              if (isPreviousCharWhitespace(arr, i)) {
                // start of space delim substring
                startPosition = i;
              }
              if (isNextCharWhitespace(arr, i)) {
                // end of space delim substring
                endPosition = i;
                // break for substring creation
                break;
              }
            }
            continue;
          }
      }

      // break's end up here
      if (startPosition > endPosition) {
        throw new IllegalArgumentException(MessageOutput.format("Illegal option values"));
      }

      // extract substring and add to List<String>
      al.add(value.substring(startPosition, ++endPosition));

      // set new start position
      i = startPosition = endPosition;
    } // for loop

    return al;
  }
 private ThreadInfo(ThreadReference thread) {
   this.thread = thread;
   if (thread == null) {
     MessageOutput.fatalError("Internal error: null ThreadInfo created");
   }
 }
  public static void main(String argv[]) throws MissingResourceException {
    redirectOutMessage();

    String cmdLine = "";
    String javaArgs = "";
    int traceFlags = VirtualMachine.TRACE_NONE;
    boolean launchImmediately = false;
    String connectSpec = null;

    MessageOutput.textResources =
        ResourceBundle.getBundle(
            "com.sun.tools.example.debug.tty.TTYResources", Locale.getDefault());

    for (int i = 0; i < argv.length; i++) {
      String token = argv[i];
      if (token.equals("-dbgtrace")) {
        if ((i == argv.length - 1) || !Character.isDigit(argv[i + 1].charAt(0))) {
          traceFlags = VirtualMachine.TRACE_ALL;
        } else {
          String flagStr = "";
          try {
            flagStr = argv[++i];
            traceFlags = Integer.decode(flagStr).intValue();
          } catch (NumberFormatException nfe) {
            usageError("dbgtrace flag value must be an integer:", flagStr);
            return;
          }
        }
      } else if (token.equals("-X")) {
        usageError("Use java minus X to see");
        return;
      } else if (
      // Standard VM options passed on
      token.equals("-v")
          || token.startsWith("-v:")
          || // -v[:...]
          token.startsWith("-verbose")
          || // -verbose[:...]
          token.startsWith("-D")
          ||
          // -classpath handled below
          // NonStandard options passed on
          token.startsWith("-X")
          ||
          // Old-style options (These should remain in place as long as
          //  the standard VM accepts them)
          token.equals("-noasyncgc")
          || token.equals("-prof")
          || token.equals("-verify")
          || token.equals("-noverify")
          || token.equals("-verifyremote")
          || token.equals("-verbosegc")
          || token.startsWith("-ms")
          || token.startsWith("-mx")
          || token.startsWith("-ss")
          || token.startsWith("-oss")) {

        javaArgs = addArgument(javaArgs, token);
      } else if (token.equals("-tclassic")) {
        usageError("Classic VM no longer supported.");
        return;
      } else if (token.equals("-tclient")) {
        // -client must be the first one
        javaArgs = "-client " + javaArgs;
      } else if (token.equals("-tserver")) {
        // -server must be the first one
        javaArgs = "-server " + javaArgs;
      } else if (token.equals("-sourcepath")) {
        if (i == (argv.length - 1)) {
          usageError("No sourcepath specified.");
          return;
        }
        Env.setSourcePath(argv[++i]);
      } else if (token.equals("-classpath")) {
        if (i == (argv.length - 1)) {
          usageError("No classpath specified.");
          return;
        }
        javaArgs = addArgument(javaArgs, token);
        javaArgs = addArgument(javaArgs, argv[++i]);
      } else if (token.equals("-attach")) {
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        if (i == (argv.length - 1)) {
          usageError("No attach address specified.");
          return;
        }
        String address = argv[++i];

        /*
         * -attach is shorthand for one of the reference implementation's
         * attaching connectors. Use the shared memory attach if it's
         * available; otherwise, use sockets. Build a connect
         * specification string based on this decision.
         */
        if (supportsSharedMemory()) {
          connectSpec = "com.sun.jdi.SharedMemoryAttach:name=" + address;
        } else {
          String suboptions = addressToSocketArgs(address);
          connectSpec = "com.sun.jdi.SocketAttach:" + suboptions;
        }
      } else if (token.equals("-listen") || token.equals("-listenany")) {
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        String address = null;
        if (token.equals("-listen")) {
          if (i == (argv.length - 1)) {
            usageError("No attach address specified.");
            return;
          }
          address = argv[++i];
        }

        /*
         * -listen[any] is shorthand for one of the reference implementation's
         * listening connectors. Use the shared memory listen if it's
         * available; otherwise, use sockets. Build a connect
         * specification string based on this decision.
         */
        if (supportsSharedMemory()) {
          connectSpec = "com.sun.jdi.SharedMemoryListen:";
          if (address != null) {
            connectSpec += ("name=" + address);
          }
        } else {
          connectSpec = "com.sun.jdi.SocketListen:";
          if (address != null) {
            connectSpec += addressToSocketArgs(address);
          }
        }
      } else if (token.equals("-launch")) {
        launchImmediately = true;
      } else if (token.equals("-listconnectors")) {
        Commands evaluator = new Commands();
        evaluator.commandConnectors(Bootstrap.virtualMachineManager());
        return;
      } else if (token.equals("-connect")) {
        /*
         * -connect allows the user to pick the connector
         * used in bringing up the target VM. This allows
         * use of connectors other than those in the reference
         * implementation.
         */
        if (connectSpec != null) {
          usageError("cannot redefine existing connection", token);
          return;
        }
        if (i == (argv.length - 1)) {
          usageError("No connect specification.");
          return;
        }
        connectSpec = argv[++i];
      } else if (token.equals("-help")) {
        usage();
      } else if (token.equals("-version")) {
        Commands evaluator = new Commands();
        evaluator.commandVersion(progname, Bootstrap.virtualMachineManager());
        System.exit(0);
      } else if (token.startsWith("-")) {
        usageError("invalid option", token);
        return;
      } else {
        // Everything from here is part of the command line
        cmdLine = addArgument("", token);
        for (i++; i < argv.length; i++) {
          cmdLine = addArgument(cmdLine, argv[i]);
        }
        break;
      }
    }

    /*
     * Unless otherwise specified, set the default connect spec.
     */

    /*
     * Here are examples of jdb command lines and how the options
     * are interpreted as arguments to the program being debugged.
     * arg1       arg2
     * ----       ----
     * jdb hello a b       a          b
     * jdb hello "a b"     a b
     * jdb hello a,b       a,b
     * jdb hello a, b      a,         b
     * jdb hello "a, b"    a, b
     * jdb -connect "com.sun.jdi.CommandLineLaunch:main=hello  a,b"   illegal
     * jdb -connect  com.sun.jdi.CommandLineLaunch:main=hello "a,b"   illegal
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a,b"'  arg1 = a,b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a b"'  arg1 = a b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello  a b'   arg1 = a  arg2 = b
     * jdb -connect 'com.sun.jdi.CommandLineLaunch:main=hello "a," b' arg1 = a, arg2 = b
     */
    if (connectSpec == null) {
      connectSpec = "com.sun.jdi.CommandLineLaunch:";
    } else if (!connectSpec.endsWith(",") && !connectSpec.endsWith(":")) {
      connectSpec += ","; // (Bug ID 4285874)
    }

    cmdLine = cmdLine.trim();
    javaArgs = javaArgs.trim();

    if (cmdLine.length() > 0) {
      if (!connectSpec.startsWith("com.sun.jdi.CommandLineLaunch:")) {
        usageError("Cannot specify command line with connector:", connectSpec);
        return;
      }
      connectSpec += "main=" + cmdLine + ",";
    }

    if (javaArgs.length() > 0) {
      if (!connectSpec.startsWith("com.sun.jdi.CommandLineLaunch:")) {
        usageError("Cannot specify target vm arguments with connector:", connectSpec);
        return;
      }
      connectSpec += "options=" + javaArgs + ",";
    }

    try {
      if (!connectSpec.endsWith(",")) {
        connectSpec += ","; // (Bug ID 4285874)
      }
      Env.init(connectSpec, launchImmediately, traceFlags);
      new ThreadDumper();
    } catch (Exception e) {
      MessageOutput.printException("Internal exception:", e);
    }
  }
 private static void usage() {
   MessageOutput.println("zz usage text", new Object[] {progname, File.pathSeparator});
   System.exit(1);
 }
 public void vmInterrupted() {
   super.vmInterrupted();
   MessageOutput.printDirectln("Jacky's vmInterrupted");
   StringTokenizer t = new StringTokenizer("where");
   executeCommand(t);
 }