1 /*
   2  * Copyright (c) 2015, 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 java.util.ArrayList;
  28 import java.util.Arrays;
  29 
  30 import sun.jvm.hotspot.tools.JStack;
  31 import sun.jvm.hotspot.tools.JMap;
  32 import sun.jvm.hotspot.tools.JInfo;
  33 
  34 public class SALauncher {
  35 
  36     private static boolean launcherHelp() {
  37         System.out.println("    clhsdb       \tcommand line debugger");
  38         System.out.println("    hsdb         \tui debugger");
  39         System.out.println("    jstack --help\tto get more information");
  40         System.out.println("    jmap   --help\tto get more information");
  41         System.out.println("    jinfo  --help\tto get more information");
  42         return false;
  43     }
  44 
  45     private static boolean commonHelp() {
  46         // --pid <pid>
  47         // --exe <exe>
  48         // --core <core>
  49         System.out.println("    --exe\texecutable image name");
  50         System.out.println("    --core\tpath to coredump");
  51         System.out.println("    --pid\tpid of process to attach");
  52         return false;
  53     }
  54 
  55     private static boolean jinfoHelp() {
  56         // --flags -> -flags
  57         // --sysprops -> -sysprops
  58         System.out.println("    --flags\tto print VM flags");
  59         System.out.println("    --sysprops\tto print Java System properties");
  60         System.out.println("    <no option>\tto print both of the above");
  61         return commonHelp();
  62     }
  63 
  64     private static boolean jmapHelp() {
  65         // --heap -> -heap
  66         // --binaryheap -> -heap:format=b
  67         // --histo -> -histo
  68         // --clstats -> -clstats
  69         // --finalizerinfo -> -finalizerinfo
  70 
  71         System.out.println("    <no option>\tto print same info as Solaris pmap");
  72         System.out.println("    --heap\tto print java heap summary");
  73         System.out.println("    --binaryheap\tto dump java heap in hprof binary format");
  74         System.out.println("    --histo\tto print histogram of java object heap");
  75         System.out.println("    --clstats\tto print class loader statistics");
  76         System.out.println("    --finalizerinfo\tto print information on objects awaiting finalization");
  77         return commonHelp();
  78     }
  79 
  80     private static boolean jstackHelp() {
  81         // --locks -> -l
  82         // --mixed -> -m
  83         System.out.println("    --locks\tto print java.util.concurrent locks");
  84         System.out.println("    --mixed\tto print both java and native frames (mixed mode)");
  85         return commonHelp();
  86     }
  87 
  88     private static boolean toolHelp(String toolName) {
  89         if (toolName.equals("jstack")) {
  90             return jstackHelp();
  91         }
  92         if (toolName.equals("jinfo")) {
  93             return jinfoHelp();
  94         }
  95         if (toolName.equals("jmap")) {
  96             return jmapHelp();
  97         }
  98         if (toolName.equals("hsdb") || toolName.equals("clhsdb")) {
  99             return commonHelp();
 100         }
 101         return launcherHelp();
 102     }
 103 
 104     private static void runCLHSDB(String[] oldArgs) {
 105         SAGetopt sg = new SAGetopt(oldArgs);
 106         String[] longOpts = {"exe=", "core=", "pid="};
 107 
 108         ArrayList<String> newArgs = new ArrayList();
 109         String exeORpid = null;
 110         String core = null;
 111         String s = null;
 112 
 113         while((s = sg.next(null, longOpts)) != null) {
 114             if (s.equals("exe")) {
 115                 exeORpid = sg.getOptarg();
 116                 continue;
 117             }
 118             if (s.equals("core")) {
 119                 core = sg.getOptarg();
 120                 continue;
 121             }
 122             if (s.equals("pid")) {
 123                 exeORpid = sg.getOptarg();
 124                 continue;
 125             }
 126         }
 127 
 128         if (exeORpid != null) {
 129             newArgs.add(exeORpid);
 130             if (core != null) {
 131                 newArgs.add(core);
 132             }
 133         }
 134         CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
 135     }
 136 
 137     private static void runHSDB(String[] oldArgs) {
 138         SAGetopt sg = new SAGetopt(oldArgs);
 139         String[] longOpts = {"exe=", "core=", "pid="};
 140 
 141         ArrayList<String> newArgs = new ArrayList();
 142         String exeORpid = null;
 143         String core = null;
 144         String s = null;
 145 
 146         while((s = sg.next(null, longOpts)) != null) {
 147             if (s.equals("exe")) {
 148                 exeORpid = sg.getOptarg();
 149                 continue;
 150             }
 151             if (s.equals("core")) {
 152                 core = sg.getOptarg();
 153                 continue;
 154             }
 155             if (s.equals("pid")) {
 156                 exeORpid = sg.getOptarg();
 157                 continue;
 158             }
 159         }
 160 
 161         if (exeORpid != null) {
 162             newArgs.add(exeORpid);
 163             if (core != null) {
 164                 newArgs.add(core);
 165             }
 166         }
 167         HSDB.main(newArgs.toArray(new String[newArgs.size()]));
 168     }
 169 
 170     private static void runJSTACK(String[] oldArgs) {
 171         SAGetopt sg = new SAGetopt(oldArgs);
 172         String[] longOpts = {"exe=", "core=", "pid=",
 173                                  "mixed", "locks"};
 174 
 175         ArrayList<String> newArgs = new ArrayList();
 176         String exeORpid = null;
 177         String core = null;
 178         String s = null;
 179 
 180         while((s = sg.next(null, longOpts)) != null) {
 181             if (s.equals("exe")) {
 182                 exeORpid = sg.getOptarg();
 183                 continue;
 184             }
 185             if (s.equals("core")) {
 186                 core = sg.getOptarg();
 187                 continue;
 188             }
 189             if (s.equals("pid")) {
 190                 exeORpid = sg.getOptarg();
 191                 continue;
 192             }
 193             if (s.equals("mixed")) {
 194                 newArgs.add("-m");
 195                 continue;
 196             }
 197             if (s.equals("locks")) {
 198                 newArgs.add("-l");
 199                 continue;
 200             }
 201         }
 202 
 203         if (exeORpid != null) {
 204             newArgs.add(exeORpid);
 205             if (core != null) {
 206                 newArgs.add(core);
 207             }
 208         }
 209 
 210         JStack.main(newArgs.toArray(new String[newArgs.size()]));
 211     }
 212 
 213     private static void runJMAP(String[] oldArgs) {
 214         SAGetopt sg = new SAGetopt(oldArgs);
 215         String[] longOpts = {"exe=", "core=", "pid=",
 216               "heap", "binaryheap", "histo", "clstats", "finalizerinfo"};
 217 
 218         ArrayList<String> newArgs = new ArrayList();
 219         String exeORpid = null;
 220         String core = null;
 221         String s = null;
 222 
 223         while((s = sg.next(null, longOpts)) != null) {
 224             if (s.equals("exe")) {
 225                 exeORpid = sg.getOptarg();
 226                 continue;
 227             }
 228             if (s.equals("core")) {
 229                 core = sg.getOptarg();
 230                 continue;
 231             }
 232             if (s.equals("pid")) {
 233                 exeORpid = sg.getOptarg();
 234                 continue;
 235             }
 236             if (s.equals("heap")) {
 237                 newArgs.add("-heap");
 238                 continue;
 239             }
 240             if (s.equals("binaryheap")) {
 241                 newArgs.add("-heap:format=b");
 242                 continue;
 243             }
 244             if (s.equals("histo")) {
 245                 newArgs.add("-histo");
 246                 continue;
 247             }
 248             if (s.equals("clstats")) {
 249                 newArgs.add("-clstats");
 250                 continue;
 251             }
 252             if (s.equals("finalizerinfo")) {
 253                 newArgs.add("-finalizerinfo");
 254                 continue;
 255             }
 256         }
 257 
 258         if (exeORpid != null) {
 259             newArgs.add(exeORpid);
 260             if (core != null) {
 261                 newArgs.add(core);
 262             }
 263         }
 264 
 265         JMap.main(newArgs.toArray(new String[newArgs.size()]));
 266     }
 267 
 268     private static void runJINFO(String[] oldArgs) {
 269         SAGetopt sg = new SAGetopt(oldArgs);
 270         String[] longOpts = {"exe=", "core=", "pid=",
 271                                      "flags", "sysprops"};
 272 
 273         ArrayList<String> newArgs = new ArrayList();
 274         String exeORpid = null;
 275         String core = null;
 276         String s = null;
 277 
 278         while((s = sg.next(null, longOpts)) != null) {
 279             if (s.equals("exe")) {
 280                 exeORpid = sg.getOptarg();
 281                 continue;
 282             }
 283             if (s.equals("core")) {
 284                 core = sg.getOptarg();
 285                 continue;
 286             }
 287             if (s.equals("pid")) {
 288                 exeORpid = sg.getOptarg();
 289                 continue;
 290             }
 291             if (s.equals("flags")) {
 292                 newArgs.add("-flags");
 293                 continue;
 294             }
 295             if (s.equals("sysprops")) {
 296                 newArgs.add("-sysprops");
 297                 continue;
 298             }
 299         }
 300 
 301         if (exeORpid != null) {
 302             newArgs.add(exeORpid);
 303             if (core != null) {
 304                 newArgs.add(core);
 305             }
 306         }
 307 
 308         JInfo.main(newArgs.toArray(new String[newArgs.size()]));
 309     }
 310 
 311     public static void main(String[] args) {
 312         // Provide a help
 313         if (args.length == 0) {
 314             launcherHelp();
 315             return;
 316         }
 317         // No arguments imply help for jstack, jmap, jinfo but launch clhsdb and hsdb
 318         if (args.length == 1 && !args[0].equals("clhsdb") && !args[0].equals("hsdb")) {
 319             toolHelp(args[0]);
 320             return;
 321         }
 322 
 323         for (String arg : args) {
 324             if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help")) {
 325                 toolHelp(args[0]);
 326                 return;
 327             }
 328         }
 329 
 330         String[] oldArgs = Arrays.copyOfRange(args, 1, args.length);
 331 
 332         // Run SA interactive mode
 333         if (args[0].equals("clhsdb")) {
 334             runCLHSDB(oldArgs);
 335             return;
 336         }
 337 
 338         if (args[0].equals("hsdb")) {
 339             runHSDB(oldArgs);
 340             return;
 341         }
 342 
 343         // Run SA tmtools mode
 344         if (args[0].equals("jstack")) {
 345             runJSTACK(oldArgs);
 346             return;
 347         }
 348 
 349         if (args[0].equals("jmap")) {
 350             runJMAP(oldArgs);
 351             return;
 352         }
 353 
 354         if (args[0].equals("jinfo")) {
 355             runJINFO(oldArgs);
 356             return;
 357         }
 358     }
 359 }