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
25package sun.jvm.hotspot;
26
27import sun.jvm.hotspot.debugger.*;
28import sun.jvm.hotspot.runtime.*;
29import sun.jvm.hotspot.oops.*;
30
31public class DebugServer {
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
44  public static void main(String[] args) {
45    new DebugServer().run(args);
46  }
47
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