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