JDTrace.java revision ae94d716ff8759d2dc2de680b5b85a291219a4c1
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
/**
* Emulates {@code dtrace(1M)} using the Java DTrace API.
*/
public class JDTrace {
static {
}
"3:6:b:c:CD:ef:Fi:I:lL:m:n:o:p:P:qs:U:vVwx:X:Z";
static boolean heading = false;
static boolean quiet = false;
static boolean flow = false;
static int stackindent = 14;
static int exitStatus = 0;
static boolean started;
static boolean stopped;
static final int QUANTIZE_ZERO_BUCKET = 63;
enum Mode {
EXEC,
INFO,
LIST,
}
enum ProgramType {
}
static class CompileRequest {
String s;
}
// Modify program string by expanding an incomplete probe
// description according to the requested probespec.
static void
{
int colons = 0;
case PROVIDER:
colons = 3;
break;
case MODULE:
colons = 2;
break;
case FUNCTION:
colons = 1;
break;
}
if (colons > 0) {
char ch;
int i = 0;
// Find first whitespace character not including leading
// whitespace (end of first token). Ignore whitespace
// inside a block if the block is concatenated with the
// probe description.
int npos = i;
boolean inBlock = false;
if (ch == '{') {
inBlock = true;
} else if (ch == '}') {
inBlock = false;
}
}
// libdtrace lets you concatenate multiple probe
// descriptions separated by code blocks in curly braces,
// for example genunix::'{printf("FOUND");}'::entry, as long
// as the concatenated probe descriptions begin with ':' and
// not a specific field such as 'syscall'. So to expand the
// possibly multiple probe descriptions, we need to insert
// colons before each open curly brace, and again at the end
// only if there is at least one non-whitespace (probe
// specifying) character after the last closing curly brace.
int prev_i = 0;
while (i < npos) {
for (int c = 0; c < colons; ++c) {
}
}
if (i < npos) {
}
prev_i = i;
}
// append remainder of program text
}
}
static void
{
if (bytes == 1) {
} else if (bytes == 2) {
} else {
}
} else {
}
}
static void
{
}
if (!heading) {
if (flow) {
} else {
if (!quiet) {
"CPU", "ID", "FUNCTION:NAME");
}
}
heading = true;
}
if (flow) {
// indent
for (int i = 0; i < indent; ++i) {
}
// prefix
case ENTRY:
if (indent == 0) {
} else {
}
break;
case RETURN:
if (indent == 0) {
} else {
}
break;
}
case NONE:
break;
default:
}
} else {
if (!quiet) {
}
}
if (record instanceof ExitRecord) {
} else if (record instanceof ScalarRecord) {
if (value instanceof byte[]) {
} else {
if (quiet) {
} else {
" %-33s");
}
}
} else if (record instanceof PrintfRecord) {
} else if (record instanceof PrintaRecord) {
} else {
}
}
}
} else if (record instanceof StackValueRecord) {
}
}
if (!quiet) {
}
}
static void
{
"------------- Distribution -------------",
"count");
long v; // bucket frequency (value)
long b; // lower bound of bucket range
double total = 0;
boolean positives = false;
boolean negatives = false;
// If possible, get one bucket before the first non-zero
// bucket and one bucket after the last.
// There isn't any data. This is possible if (and only if)
// negative increment values have been used. In this case,
// print the buckets around the base.
if (d instanceof LinearDistribution) {
b1 = 0;
b2 = 2;
} else {
}
} else {
}
v = d.get(i).getFrequency();
if (v > 0) {
positives = true;
}
if (v < 0) {
negatives = true;
}
}
v = bucket.getFrequency();
if ((d instanceof LinearDistribution) ||
(d instanceof LogLinearDistribution)) {
if (d instanceof LinearDistribution)
else
} else {
}
} else {
}
}
}
static void
boolean negatives)
{
double f;
if (!negatives) {
if (positives) {
depth = (int)(f + 0.5);
} else {
depth = 0;
}
return;
}
if (!positives) {
depth = (int)(f + 0.5);
return;
}
/*
* If we're here, we have both positive and negative bucket values.
* To express this graphically, we're going to generate both positive
* and negative bars separated by a centerline. These bars are half
* the size of normal quantize()/lquantize() bars, so we divide the
* length in half before calculating the bar length.
*/
len /= 2;
depth = (int)(f + 0.5);
if (val <= 0) {
return;
} else {
}
}
public static String
{
for (int i = 0; i < n; ++i) {
}
}
static void
{
int i;
String s;
for (StackFrame f : frames) {
for (i = 0; i < stackindent; ++i) {
}
s = f.getFrame();
}
}
}
static void
{
}
static void
{
int i;
int len;
for (AggregationRecord r : list) {
for (i = 0; i < len; ++i) {
if (tupleRecord instanceof StackValueRecord) {
} else if (tupleRecord instanceof SymbolValueRecord) {
} else {
" %-50s");
}
}
if (value instanceof Distribution) {
} else {
}
}
}
static void
{
if (status == 0) {
status = exitStatus;
}
}
static void
usage()
{
"[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] " +
"[-o output] [-p pid] [-s script] [-U name]\n\t" +
"[-x opt[=val]] [-X a|c|s|t]\n\n" +
"\t[-P provider %s]\n" +
"\t[-m [ provider: ] module %s]\n" +
"\t[-f [[ provider: ] module: ] func %s]\n" +
"\t[-n [[[ provider: ] module: ] func: ] name %s]\n" +
"\t[-i probe-id %s] [ args ... ]\n\n", CLASSNAME,
"\t-32 generate 32-bit D programs\n" +
"\t-64 generate 64-bit D programs\n\n" +
"\t-b set trace buffer size\n" +
"\t-c run specified command and exit upon its completion\n" +
"\t-C run cpp(1) preprocessor on script files\n" +
"\t-D define symbol when invoking preprocessor\n" +
"\t-e exit after compiling request but prior to enabling " +
"probes\n" +
"\t-f enable or list probes matching the specified " +
"function name\n" +
"\t-F coalesce trace output by function\n" +
"\t-i enable or list probes matching the specified probe id\n" +
"\t-I add include directory to preprocessor search path\n" +
"\t-l list probes matching specified criteria\n" +
"\t-L add library directory to library search path\n" +
"\t-m enable or list probes matching the specified " +
"module name\n" +
"\t-n enable or list probes matching the specified probe name\n" +
"\t-o set output file\n" +
"\t-p grab specified process-ID and cache its symbol tables\n" +
"\t-P enable or list probes matching the specified " +
"provider name\n" +
"\t-q set quiet mode (only output explicitly traced data)\n" +
"\t-s enable or list probes according to the specified " +
"D script\n" +
"\t-U undefine symbol when invoking preprocessor\n" +
"\t-v set verbose mode (report stability attributes, " +
"arguments)\n" +
"\t-V report DTrace API version\n" +
"\t-w permit destructive actions\n" +
"\t-x enable or modify compiler and tracing options\n" +
"\t-X specify ISO C conformance settings for preprocessor\n" +
"\t-Z permit probe descriptions that match zero probes\n" +
"\n" +
"\tTo log PrintaRecord, set this environment variable:\n" +
"\t\tJDTRACE_LOGGING_LEVEL=FINE\n" +
"\tTo log ProbeData, set JDTRACE_LOGGING_LEVEL=FINER\n");
exit(2);
}
static void
{
"attributes");
a = info.getMinimumProbeAttributes();
a.getNameStability());
a.getDataStability());
a.getDependencyClass());
a.getNameStability());
a.getDataStability());
a.getDependencyClass());
}
static void
{
p.getProvider(), p.getModule(),
p.getFunction(), p.getName());
}
static void
{
a = p.getProbeAttributes();
a.getNameStability());
a.getDataStability());
a.getDependencyClass());
a = p.getArgumentAttributes();
a.getNameStability());
a.getDataStability());
a.getDependencyClass());
// Argument types unsupported for now.
}
public static void
{
try {
} catch (Exception e) {
}
usage();
}
<CompileRequest> ();
boolean verbose = false;
public void handleException(Throwable e) {
if (e instanceof DTraceException) {
} else if (e instanceof ConsumerException) {
} else {
}
} else {
e.printStackTrace();
}
exit(1);
}
};
int c = 0;
while ((c = g.getopt()) != -1) {
switch (c) {
case '3': {
if (!s.equals("2")) {
usage();
}
break;
}
case '6': {
if (!s.equals("4")) {
usage();
}
break;
}
}
}
dtrace = new LocalConsumer() {
protected Thread createThread() {
Thread t = super.createThread();
t.setDaemon(false);
return t;
}
};
c = 0;
try {
// Set default options that may be overriden by options or #pragma
while ((c = g.getopt()) != -1) {
switch (c) {
case 'b':
break;
case 'c':
break;
case 'C':
break;
case 'D':
break;
case 'e':
break;
case 'f':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'F':
break;
case 'i':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'I':
break;
case 'l':
break;
case 'L':
break;
case 'm':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'n':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'o':
try {
outFile, true);
} catch (FileNotFoundException e) {
outFileName + " in write mode");
exit(1);
} catch (SecurityException e) {
exit(1);
}
break;
case 'p':
int pid = -1;
try {
} catch (NumberFormatException e) {
exit(1);
}
break;
case 'P':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'q':
break;
case 's':
r = new CompileRequest();
r.s = g.getOptarg();
compileRequests.add(r);
break;
case 'U':
break;
case 'v':
verbose = true;
break;
case 'V':
break;
case 'w':
break;
case 'x':
}
break;
case 'X':
break;
case 'Z':
break;
case '?':
usage(); // getopt() already printed an error
break;
default:
c = 0;
}
}
c = 0;
}
exit(0);
}
case STRING:
break;
case FILE:
break;
default:
throw new IllegalArgumentException(
}
}
// Get options set by #pragmas in compiled program
long optval;
stackindent = (int)optval;
}
"ID", "PROVIDER", "MODULE", "FUNCTION", "NAME");
if (verbose) {
for (Program p : programList) {
}
p = probe.getDescription();
}
}
} else {
for (Program p : programList) {
}
for (ProbeDescription p : list) {
}
}
}
exit(0);
}
for (Program p : programList) {
programType = "script";
} else {
programType = "description";
}
} else {
dtrace.getProgramInfo(p);
}
}
if (verbose) {
}
}
exit(0);
}
public void consumerStarted(ConsumerEvent e) {
started = true;
}
public void consumerStopped(ConsumerEvent e) {
stopped = true;
try {
}
} catch (Throwable x) {
}
exit(0);
}
public void dataDropped(DropEvent e) {
e.getDrop().getDefaultMessage());
}
public void errorEncountered(ErrorEvent e)
throws ConsumerException {
}
}
public void dataReceived(DataEvent e)
throws ConsumerException {
consumeProbeData(e.getProbeData());
}
public void processStateChanged(ProcessEvent e)
throws ConsumerException {
}
}
});
// Print unprinted aggregations after Ctrl-C
public void run() {
return;
}
try {
}
} catch (Throwable x) {
}
}
});
} catch (DTraceException e) {
if (c > 0) {
// set option error
c, e.getMessage());
} else {
c, g.getOptarg(), e.getMessage());
}
} else {
// any other error
}
exit(1);
} catch (Exception e) {
e.printStackTrace();
exit(1);
}
}
}