1 /*
   2  * Copyright 2000-2003 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 import sun.jvm.hotspot.debugger.dbx.*;
  29 import sun.jvm.hotspot.runtime.*;
  30 import sun.jvm.hotspot.oops.*;
  31 
  32 public class DebugServer {
  33   private void usage() {
  34     System.out.println("usage: java " + getClass().getName() + " <pid> [server id]");
  35     System.out.println("   or: java " + getClass().getName() + " <executable> <core> [server id]");
  36     System.out.println("\"pid\" must be the process ID of a HotSpot process.");
  37     System.out.println("If reading a core file, \"executable\" must (currently) be the");
  38     System.out.println("full path name to the precise java executable which generated");
  39     System.out.println("the core file (not, on Solaris, the \"java\" wrapper script in");
  40     System.out.println("the \"bin\" subdirectory of the JDK.)");
  41     System.out.println("The \"server id\" is a unique name for a specific remote debuggee.");
  42     System.exit(1);
  43   }
  44 
  45   public static void main(String[] args) {
  46     new DebugServer().run(args);
  47   }
  48 
  49   private void run(String[] args) {
  50     if ((args.length < 1) || (args.length > 3)) {
  51       usage();
  52     }
  53 
  54     // Attempt to handle "-h" or "-help"
  55     if (args[0].startsWith("-")) {
  56       usage();
  57     }
  58 
  59     int pid = 0;
  60     boolean usePid = false;
  61     String coreFileName = null;
  62     // FIXME: would be nice to pick this up from the core file
  63     // somehow, but that doesn't look possible. Should at least figure
  64     // it out from a path to the JDK.
  65     String javaExecutableName = null;
  66     String serverID = null;
  67 
  68     switch (args.length) {
  69        case 1:
  70          try {
  71            pid = Integer.parseInt(args[0]);
  72            usePid = true;
  73          } catch (NumberFormatException e) {
  74            usage();
  75          }
  76          break;
  77 
  78        case 2:
  79          // either we have pid and server id or exec file and core file
  80          try {
  81            pid = Integer.parseInt(args[0]);
  82            usePid = true;
  83            serverID = args[1];
  84          } catch (NumberFormatException e) {
  85            pid = -1;
  86            usePid = false;
  87            javaExecutableName = args[0];
  88            coreFileName = args[1];
  89          }
  90          break;
  91 
  92        case 3:
  93          javaExecutableName = args[0];
  94          coreFileName = args[1];
  95          serverID = args[2];
  96          break;
  97 
  98        default:
  99          // should not happend, taken care already.
 100          break;
 101     }
 102 
 103     final HotSpotAgent agent = new HotSpotAgent();
 104     try {
 105       if (usePid) {
 106         System.err.println("Attaching to process ID " + pid + " and starting RMI services, please wait...");
 107         agent.startServer(pid, serverID);
 108       } else {
 109         System.err.println("Attaching to core " + coreFileName +
 110                            " from executable " + javaExecutableName + " and starting RMI services, please wait...");
 111         agent.startServer(javaExecutableName, coreFileName, serverID);
 112       }
 113     }
 114     catch (DebuggerException e) {
 115       if (usePid) {
 116         System.err.print("Error attaching to process or starting server: ");
 117       } else {
 118         System.err.print("Error attaching to core file or starting server: ");
 119       }
 120       e.printStackTrace();
 121       System.exit(1);
 122     }
 123 
 124     // shutdown hook to clean-up the server in case of forced exit.
 125     Runtime.getRuntime().addShutdownHook(new java.lang.Thread(
 126                           new Runnable() {
 127                              public void run() {
 128                                 agent.shutdownServer();
 129                              }
 130                           }));
 131     System.err.println("Debugger attached and RMI services started.");
 132   }
 133 }