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