All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.btrace.client.Main Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2008-2010 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.btrace.client;

import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import sun.misc.Signal;
import sun.misc.SignalHandler;
import com.sun.btrace.CommandListener;
import com.sun.btrace.comm.Command;
import com.sun.btrace.comm.DataCommand;
import com.sun.btrace.comm.ErrorCommand;
import com.sun.btrace.comm.ExitCommand;
import com.sun.btrace.util.Messages;

/**
 * This is the main class for a simple command line
 * BTrace client. It is possible to create a GUI
 * client using the Client class.
 *
 * @author A. Sundararajan
 */
public final class Main {
    public static volatile boolean exiting;
    public static final boolean DEBUG;
    public static final boolean TRACK_RETRANSFORM;
    public static final boolean UNSAFE;
    public static final boolean DUMP_CLASSES;
    public static final String DUMP_DIR;
    public static final String PROBE_DESC_PATH;
    public static final int BTRACE_DEFAULT_PORT = 2020;
    
    private static final Console con;
    private static final PrintWriter out;
    static {
        DEBUG = Boolean.getBoolean("com.sun.btrace.debug");
        if (isDebug()) debugPrint("btrace debug mode is set");
        TRACK_RETRANSFORM = Boolean.getBoolean("com.sun.btrace.trackRetransforms");
        if (isDebug() && TRACK_RETRANSFORM) debugPrint("trackRetransforms flag is set");
        UNSAFE = Boolean.getBoolean("com.sun.btrace.unsafe");
        if (isDebug() && UNSAFE) debugPrint("btrace unsafe mode is set");
        DUMP_CLASSES = Boolean.getBoolean("com.sun.btrace.dumpClasses");
        if (isDebug() && DUMP_CLASSES) debugPrint("dumpClasses flag is set");
        DUMP_DIR = System.getProperty("com.sun.btrace.dumpDir", ".");
        if (DUMP_CLASSES) {
            if (isDebug()) debugPrint("dumpDir is " + DUMP_DIR);
        }
        PROBE_DESC_PATH = System.getProperty("com.sun.btrace.probeDescPath", ".");
        con = System.console();
        out = (con != null)? con.writer() : new PrintWriter(System.out);
    }
    
    public static void main(String[] args) {
        if (args.length < 2) {
            usage();
        }

        int port = BTRACE_DEFAULT_PORT;
        String classPath = ".";
        String includePath = null;
        
        int count = 0;
        boolean portDefined = false;
        boolean classpathDefined = false;
        boolean includePathDefined = false;

        for (;;) {
            if (args[count].charAt(0) == '-') {
                if (args.length <= count+1) {
                    usage();
                }  
                if (args[count].equals("-p") && !portDefined) {
                    try {
                        port = Integer.parseInt(args[++count]);
                        if (isDebug()) debugPrint("accepting port " + port);
                    } catch (NumberFormatException nfe) {
                        usage();
                    }
                    portDefined = true;
                } else if ((args[count].equals("-cp") ||
                    args[count].equals("-classpath"))
                    && !classpathDefined) {
                    classPath = args[++count];
                    if (isDebug()) debugPrint("accepting classpath " + classPath);
                    classpathDefined = true;
                } else if (args[count].equals("-I") && !includePathDefined) {
                    includePath = args[++count];
                    if (isDebug()) debugPrint("accepting include path " + includePath);
                    includePathDefined = true;
                } else {
                    usage();
                }
                count++;
                if (count >= args.length) {
                    break;
                }
            } else {
                break;
            }
        }

        if (! portDefined) {
            if (isDebug()) debugPrint("assuming default port " + port);
        }

        if (! classpathDefined) {
            if (isDebug()) debugPrint("assuming default classpath '" + classPath + "'");
        }

        if (args.length < (count + 1)) {
            usage();
        }

        String pid = args[count];
        String fileName = args[count + 1];
        String[] btraceArgs = new String[args.length - count];
        if (btraceArgs.length > 0) {
            System.arraycopy(args, count, btraceArgs, 0, btraceArgs.length);
        }

        try {
            Client client = new Client(port, PROBE_DESC_PATH, 
                DEBUG, TRACK_RETRANSFORM, UNSAFE, DUMP_CLASSES, DUMP_DIR);
            if (! new File(fileName).exists()) {
                errorExit("File not found: " + fileName, 1);
            }
            byte[] code = client.compile(fileName, classPath, includePath);
            if (code == null) { 
                errorExit("BTrace compilation failed", 1);
            }
            client.attach(pid);
            registerExitHook(client);
            if (con != null) {
                registerSignalHandler(client);
            }
            if (isDebug()) debugPrint("submitting the BTrace program");
            client.submit(fileName, code, btraceArgs,
                createCommandListener(client));
        } catch (IOException exp) {
            errorExit(exp.getMessage(), 1);
        }
    }

    private static CommandListener createCommandListener(Client client) {
        return new CommandListener() {
            public void onCommand(Command cmd) throws IOException {
                int type = cmd.getType();
                if (cmd instanceof DataCommand) {
                    ((DataCommand)cmd).print(out);
                    out.flush();
                } else if (type == Command.EXIT) {
                    exiting = true;
                    ExitCommand ecmd = (ExitCommand)cmd;
                    System.exit(ecmd.getExitCode());
                } else if (type == Command.ERROR) {
                    ErrorCommand ecmd = (ErrorCommand)cmd;
                    Throwable cause = ecmd.getCause();
                    if (cause != null) {
                        cause.printStackTrace();
                    }
                }
            }
        };
    }

    private static void registerExitHook(final Client client) {
        if (isDebug()) debugPrint("registering shutdown hook");
        Runtime.getRuntime().addShutdownHook(new Thread(
            new Runnable() {
                public void run() {
                    if (! exiting) {
                        try {
                            if (isDebug()) debugPrint("sending exit command");
                            client.sendExit(0);
                        } catch (IOException ioexp) {
                            if (isDebug()) debugPrint(ioexp.toString());
                        }
                    }
                }
            }));
    }

    private static void registerSignalHandler(final Client client) {
        if (isDebug()) debugPrint("registering signal handler for SIGINT");            
        Signal.handle(new Signal("INT"), 
            new SignalHandler() {
                public void handle(Signal sig) {
                    try {
                        con.printf("Please enter your option:\n");
                        con.printf("\t1. exit\n\t2. send an event\n\t3. send a named event\n");
                        con.flush();
                        String option = con.readLine();
                        option = option.trim();
                        if (option == null) {
                            return;
                        }
                        if (option.equals("1")) {                            
                            System.exit(0);
                        } else if (option.equals("2")) {
                            if (isDebug()) debugPrint("sending event command");
                            client.sendEvent();
                        } else if (option.equals("3")) {
                            con.printf("Please enter the event name: ");
                            String name = con.readLine();
                            if (name != null) {
                                if (isDebug()) debugPrint("sending event command");
                                client.sendEvent(name);
                            }
                        } else {
                            con.printf("invalid option!\n");
                        }
                    } catch (IOException ioexp) {
                        if (isDebug()) debugPrint(ioexp.toString());
                    }
                }
            });
    }

    private static void usage() {
        System.err.println(Messages.get("btrace.usage"));
        System.exit(1);
    }

    private static boolean isDebug() {
        return DEBUG;
    }

    private static boolean isUnsafe() {
        return UNSAFE;
    }

    private static void debugPrint(String msg) {
        System.out.println("DEBUG: " + msg);
    }

    private static void errorExit(String msg, int code) {
        exiting = true;
        System.err.println(msg);
        System.exit(code);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy