diff options
Diffstat (limited to 'usr/src')
21 files changed, 1389 insertions, 154 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_aggregate.c b/usr/src/lib/libdtrace/common/dt_aggregate.c index 922dec49be..1d3b1f0f35 100644 --- a/usr/src/lib/libdtrace/common/dt_aggregate.c +++ b/usr/src/lib/libdtrace/common/dt_aggregate.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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 * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -729,16 +729,36 @@ dt_aggregate_keycmp(const void *lhs, const void *rhs) break; default: - for (j = 0; j < lrec->dtrd_size; j++) { - lval = ((uint8_t *)ldata)[j]; - rval = ((uint8_t *)rdata)[j]; + switch (lrec->dtrd_action) { + case DTRACEACT_UMOD: + case DTRACEACT_UADDR: + case DTRACEACT_USYM: + for (j = 0; j < 2; j++) { + /* LINTED - alignment */ + lval = ((uint64_t *)ldata)[j]; + /* LINTED - alignment */ + rval = ((uint64_t *)rdata)[j]; + + if (lval < rval) + return (DT_LESSTHAN); + + if (lval > rval) + return (DT_GREATERTHAN); + } - if (lval < rval) - return (DT_LESSTHAN); + break; - if (lval > rval) - return (DT_GREATERTHAN); + default: + for (j = 0; j < lrec->dtrd_size; j++) { + lval = ((uint8_t *)ldata)[j]; + rval = ((uint8_t *)rdata)[j]; + if (lval < rval) + return (DT_LESSTHAN); + + if (lval > rval) + return (DT_GREATERTHAN); + } } continue; diff --git a/usr/src/lib/libdtrace_jni/common/dtj_consume.c b/usr/src/lib/libdtrace_jni/common/dtj_consume.c index 952e7f3225..e656ff5ba5 100644 --- a/usr/src/lib/libdtrace_jni/common/dtj_consume.c +++ b/usr/src/lib/libdtrace_jni/common/dtj_consume.c @@ -76,9 +76,15 @@ static jobject dtj_new_stack_record(const caddr_t, const dtrace_recdesc_t *, dtj_java_consumer_t *); static jobject dtj_new_probedata_stack_record(const dtrace_probedata_t *, const dtrace_recdesc_t *, dtj_java_consumer_t *); +static jobject dtj_new_symbol_record(const caddr_t, const dtrace_recdesc_t *, + dtj_java_consumer_t *); +static jobject dtj_new_probedata_symbol_record(const dtrace_probedata_t *, + const dtrace_recdesc_t *, dtj_java_consumer_t *); /* Aggregation data */ static jobject dtj_new_tuple_stack_record(const dtrace_aggdata_t *, const dtrace_recdesc_t *, const char *, dtj_java_consumer_t *); +static jobject dtj_new_tuple_symbol_record(const dtrace_aggdata_t *, + const dtrace_recdesc_t *, const char *, dtj_java_consumer_t *); static jobject dtj_new_distribution(const dtrace_aggdata_t *, const dtrace_recdesc_t *, dtj_java_consumer_t *); static jobject dtj_new_aggval(dtj_java_consumer_t *, const dtrace_aggdata_t *, @@ -92,9 +98,10 @@ static void dtj_aggwalk_init(dtj_java_consumer_t *); static int dtj_agghandler(const dtrace_bufdata_t *, dtj_java_consumer_t *); static boolean_t dtj_is_included(const dtrace_aggdata_t *, dtj_java_consumer_t *); -static void dtj_attach_frames(dtj_java_consumer_t *, jobject, - jobjectArray); +static void dtj_attach_frames(dtj_java_consumer_t *, jobject, jobjectArray); +static void dtj_attach_name(dtj_java_consumer_t *, jobject, jstring); static boolean_t dtj_is_stack_action(dtrace_actkind_t); +static boolean_t dtj_is_symbol_action(dtrace_actkind_t); static int dtj_clear(const dtrace_aggdata_t *, void *); /* @@ -134,12 +141,6 @@ dtj_set_callback_handlers(dtj_java_consumer_t *jc) dtrace_hdl_t *dtp = jc->dtjj_consumer->dtjc_dtp; dtrace_optval_t optval; - /* - * The user argument to the bufhandler is the lookup key used to obtain - * the thread-specific java consumer. The java consumer contains JNI - * state specific to either the consumer loop or the getAggregate() - * call. - */ if (dtrace_handle_buffered(dtp, &dtj_bufhandler, NULL) == -1) { dtj_throw_dtrace_exception(jc, "failed to establish buffered handler: %s", @@ -562,16 +563,17 @@ dtj_recdata(dtj_java_consumer_t *jc, uint32_t size, caddr_t addr) { JNIEnv *jenv = jc->dtjj_jenv; jobject jobj; + jobject jrec; switch (size) { case 1: - jobj = (*jenv)->NewObject(jenv, g_byte_jc, - g_byteinit_jm, *((char *)addr)); + jobj = (*jenv)->NewObject(jenv, g_int_jc, + g_intinit_jm, (int)(*((uint8_t *)addr))); break; case 2: - jobj = (*jenv)->NewObject(jenv, g_short_jc, + jobj = (*jenv)->NewObject(jenv, g_int_jc, /* LINTED - alignment */ - g_shortinit_jm, *((int16_t *)addr)); + g_intinit_jm, (int)(*((uint16_t *)addr))); break; case 4: jobj = (*jenv)->NewObject(jenv, g_int_jc, @@ -588,7 +590,15 @@ dtj_recdata(dtj_java_consumer_t *jc, uint32_t size, caddr_t addr) break; } - return (jobj); + if (!jobj) { + return (NULL); /* OutOfMemoryError pending */ + } + + jrec = (*jenv)->NewObject(jenv, g_scalar_jc, + g_scalarinit_jm, jobj, size); + (*jenv)->DeleteLocalRef(jenv, jobj); + + return (jrec); } /* @@ -909,6 +919,9 @@ dtj_chew(const dtrace_probedata_t *data, void *arg) if (dtj_is_stack_action(rec->dtrd_action)) { jobj = dtj_new_probedata_stack_record(data, rec, jc); + } else if (dtj_is_symbol_action(rec->dtrd_action)) { + jobj = dtj_new_probedata_symbol_record(data, + rec, jc); } else { jobj = dtj_recdata(jc, rec->dtrd_size, (data->dtpda_data + rec->dtrd_offset)); @@ -1095,6 +1108,26 @@ dtj_bufhandler(const dtrace_bufdata_t *bufdata, void *arg) return (DTRACE_HANDLE_ABORT); } break; + case DTRACEACT_USYM: + case DTRACEACT_UADDR: + case DTRACEACT_UMOD: + case DTRACEACT_SYM: + case DTRACEACT_MOD: + /* stand-alone symbol lookup action */ + jstr = (*jenv)->NewStringUTF(jenv, s); + if (!jstr) { + /* OutOfMemoryError pending */ + return (DTRACE_HANDLE_ABORT); + } + (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata, + g_pdataadd_symbol_jm, + jc->dtjj_consumer->dtjc_probedata_rec_i, jstr); + (*jenv)->DeleteLocalRef(jenv, jstr); + if ((*jenv)->ExceptionCheck(jenv)) { + WRAP_EXCEPTION(jenv); + return (DTRACE_HANDLE_ABORT); + } + break; default: /* * The record handler dtj_chewrec() defers nothing else to this @@ -1122,6 +1155,24 @@ dtj_is_stack_action(dtrace_actkind_t act) return (stack_action); } +static boolean_t +dtj_is_symbol_action(dtrace_actkind_t act) +{ + boolean_t symbol_action; + switch (act) { + case DTRACEACT_USYM: + case DTRACEACT_UADDR: + case DTRACEACT_UMOD: + case DTRACEACT_SYM: + case DTRACEACT_MOD: + symbol_action = B_TRUE; + break; + default: + symbol_action = B_FALSE; + } + return (symbol_action); +} + /* * Called by get_aggregate() to clear only those aggregations specified by the * caller. @@ -1229,6 +1280,58 @@ dtj_new_tuple_stack_record(const dtrace_aggdata_t *data, dtj_attach_frames(jc, jobj, frames); (*jenv)->DeleteLocalRef(jenv, frames); if ((*jenv)->ExceptionCheck(jenv)) { + WRAP_EXCEPTION(jenv); + return (NULL); + } + + return (jobj); +} + +static jobject +dtj_new_probedata_symbol_record(const dtrace_probedata_t *data, + const dtrace_recdesc_t *rec, dtj_java_consumer_t *jc) +{ + caddr_t addr; + + addr = data->dtpda_data + rec->dtrd_offset; + return (dtj_new_symbol_record(addr, rec, jc)); +} + +static jobject +dtj_new_tuple_symbol_record(const dtrace_aggdata_t *data, + const dtrace_recdesc_t *rec, const char *s, dtj_java_consumer_t *jc) +{ + caddr_t addr; + JNIEnv *jenv = jc->dtjj_jenv; + + jobject jobj = NULL; /* tuple element */ + jstring jstr = NULL; /* lookup value */ + jstring tstr = NULL; /* trimmed lookup value */ + + addr = data->dtada_data + rec->dtrd_offset; + jobj = dtj_new_symbol_record(addr, rec, jc); + if (!jobj) { + return (NULL); /* java exception pending */ + } + + /* Get symbol lookup */ + jstr = (*jenv)->NewStringUTF(jenv, s); + if (!jstr) { + /* OutOfMemoryError pending */ + (*jenv)->DeleteLocalRef(jenv, jobj); + return (NULL); + } + /* Trim leading and trailing whitespace */ + tstr = (*jenv)->CallObjectMethod(jenv, jstr, g_trim_jm); + /* trim() returns a new string; don't leak the old one */ + (*jenv)->DeleteLocalRef(jenv, jstr); + jstr = tstr; + tstr = NULL; + + dtj_attach_name(jc, jobj, jstr); + (*jenv)->DeleteLocalRef(jenv, jstr); + if ((*jenv)->ExceptionCheck(jenv)) { + WRAP_EXCEPTION(jenv); return (NULL); } @@ -1249,7 +1352,7 @@ dtj_aggwalk_init(dtj_java_consumer_t *jc) } static jobject -dtj_new_stack_record(caddr_t addr, const dtrace_recdesc_t *rec, +dtj_new_stack_record(const caddr_t addr, const dtrace_recdesc_t *rec, dtj_java_consumer_t *jc) { JNIEnv *jenv = jc->dtjj_jenv; @@ -1306,6 +1409,48 @@ dtj_new_stack_record(caddr_t addr, const dtrace_recdesc_t *rec, return (stack); } +static jobject +dtj_new_symbol_record(const caddr_t addr, const dtrace_recdesc_t *rec, + dtj_java_consumer_t *jc) +{ + JNIEnv *jenv = jc->dtjj_jenv; + + dtrace_actkind_t act; + uint64_t *pc; + pid_t pid = -1; + + jobject symbol = NULL; /* return value */ + + act = rec->dtrd_action; + switch (act) { + case DTRACEACT_SYM: + case DTRACEACT_MOD: + /* LINTED - alignment */ + pc = (uint64_t *)addr; + symbol = (*jenv)->NewObject(jenv, g_symbol_jc, + g_symbolinit_jm, *pc); + break; + case DTRACEACT_USYM: + case DTRACEACT_UADDR: + case DTRACEACT_UMOD: + /* Get pid of user process */ + pc = (uint64_t *)(uintptr_t)addr; + pid = (pid_t)*pc; + ++pc; + symbol = (*jenv)->NewObject(jenv, g_usymbol_jc, + g_usymbolinit_jm, pid, *pc); + break; + default: + dtj_throw_illegal_argument(jenv, + "Expected stack action, got %d\n", act); + } + if ((*jenv)->ExceptionCheck(jenv)) { + WRAP_EXCEPTION(jenv); + return (NULL); + } + return (symbol); +} + /* * Return NULL if java exception pending, otherwise return Distribution value. */ @@ -1408,6 +1553,18 @@ dtj_attach_frames(dtj_java_consumer_t *jc, jobject stack, } } +static void +dtj_attach_name(dtj_java_consumer_t *jc, jobject symbol, jstring s) +{ + JNIEnv *jenv = jc->dtjj_jenv; + + if ((*jenv)->IsInstanceOf(jenv, symbol, g_symbol_jc)) { + (*jenv)->CallVoidMethod(jenv, symbol, g_symbolset_name_jm, s); + } else if ((*jenv)->IsInstanceOf(jenv, symbol, g_usymbol_jc)) { + (*jenv)->CallVoidMethod(jenv, symbol, g_usymbolset_name_jm, s); + } +} + /* * Note: It is not valid to look outside the current libdtrace record in the * given aggdata (except to get the aggregation ID from the first record). @@ -1541,6 +1698,13 @@ dtj_agghandler(const dtrace_bufdata_t *bufdata, dtj_java_consumer_t *jc) case DTRACEACT_JSTACK: jobj = dtj_new_tuple_stack_record(aggdata, rec, s, jc); break; + case DTRACEACT_USYM: + case DTRACEACT_UADDR: + case DTRACEACT_UMOD: + case DTRACEACT_SYM: + case DTRACEACT_MOD: + jobj = dtj_new_tuple_symbol_record(aggdata, rec, s, jc); + break; default: jobj = dtj_recdata(jc, rec->dtrd_size, (aggdata->dtada_data + rec->dtrd_offset)); diff --git a/usr/src/lib/libdtrace_jni/common/dtj_jnitab.c b/usr/src/lib/libdtrace_jni/common/dtj_jnitab.c index f0f4cc6c8e..906a262a60 100644 --- a/usr/src/lib/libdtrace_jni/common/dtj_jnitab.c +++ b/usr/src/lib/libdtrace_jni/common/dtj_jnitab.c @@ -109,6 +109,7 @@ jmethodID g_pdataadd_jm = 0; jmethodID g_pdataadd_rec_jm = 0; jmethodID g_pdataadd_trace_jm = 0; jmethodID g_pdataadd_stack_jm = 0; +jmethodID g_pdataadd_symbol_jm = 0; jmethodID g_pdataadd_printf_jm = 0; jmethodID g_pdataadd_printa_jm = 0; jmethodID g_pdatainvalidate_printa_jm = 0; @@ -197,6 +198,20 @@ jmethodID g_distinit_jm = 0; jclass g_ldist_jc = 0; jmethodID g_ldistinit_jm = 0; +/* KernelSymbolRecord */ +jclass g_symbol_jc = 0; +jmethodID g_symbolinit_jm = 0; +jmethodID g_symbolset_name_jm = 0; + +/* UserSymbolRecord */ +jclass g_usymbol_jc = 0; +jmethodID g_usymbolinit_jm = 0; +jmethodID g_usymbolset_name_jm = 0; + +/* ScalarRecord */ +jclass g_scalar_jc = 0; +jmethodID g_scalarinit_jm = 0; + static dtj_status_t dtj_table_load(JNIEnv *jenv) @@ -292,12 +307,14 @@ dtj_table_load(JNIEnv *jenv) "(IILorg/opensolaris/os/dtrace/ProbeDescription;" "Lorg/opensolaris/os/dtrace/Flow;I)V" }, { JMETHOD, &g_pdataadd_jm, "addDataElement", - "(Ljava/lang/Object;)V" }, + "(Lorg/opensolaris/os/dtrace/Record;)V" }, { JMETHOD, &g_pdataadd_rec_jm, "addRecord", "(Lorg/opensolaris/os/dtrace/Record;)V" }, { JMETHOD, &g_pdataadd_trace_jm, "addTraceRecord", "(I)V" }, { JMETHOD, &g_pdataadd_stack_jm, "addStackRecord", "(ILjava/lang/String;)V" }, + { JMETHOD, &g_pdataadd_symbol_jm, "addSymbolRecord", + "(ILjava/lang/String;)V" }, { JMETHOD, &g_pdataadd_printf_jm, "addPrintfRecord", "()V" }, { JMETHOD, &g_pdataadd_printa_jm, "addPrintaRecord", "(JZ)V" }, { JMETHOD, &g_pdatainvalidate_printa_jm, @@ -354,7 +371,7 @@ dtj_table_load(JNIEnv *jenv) { JCLASS, &g_tuple_jc, "org/opensolaris/os/dtrace/Tuple" }, { JMETHOD, &g_tupleinit_jm, CONSTRUCTOR, "()V" }, { JMETHOD, &g_tupleadd_jm, "addElement", - "(Ljava/lang/Object;)V" }, + "(Lorg/opensolaris/os/dtrace/ValueRecord;)V" }, { JMETHOD, &g_tuplesize_jm, "size", "()I" }, { JFIELD_STATIC, &g_tuple_EMPTY_jsf, "EMPTY", "Lorg/opensolaris/os/dtrace/Tuple;" }, @@ -425,6 +442,26 @@ dtj_table_load(JNIEnv *jenv) "org/opensolaris/os/dtrace/LinearDistribution" }, { JMETHOD, &g_ldistinit_jm, CONSTRUCTOR, "(JJ[J)V" }, + /* KernelSymbolRecord */ + { JCLASS, &g_symbol_jc, + "org/opensolaris/os/dtrace/KernelSymbolRecord" }, + { JMETHOD, &g_symbolinit_jm, CONSTRUCTOR, "(J)V" }, + { JMETHOD, &g_symbolset_name_jm, "setSymbol", + "(Ljava/lang/String;)V" }, + + /* UserSymbolRecord */ + { JCLASS, &g_usymbol_jc, + "org/opensolaris/os/dtrace/UserSymbolRecord" }, + { JMETHOD, &g_usymbolinit_jm, CONSTRUCTOR, "(IJ)V" }, + { JMETHOD, &g_usymbolset_name_jm, "setSymbol", + "(Ljava/lang/String;)V" }, + + /* ScalarRecord */ + { JCLASS, &g_scalar_jc, + "org/opensolaris/os/dtrace/ScalarRecord" }, + { JMETHOD, &g_scalarinit_jm, CONSTRUCTOR, + "(Ljava/lang/Object;I)V" }, + { DTJ_TYPE_END } }; diff --git a/usr/src/lib/libdtrace_jni/common/dtrace_jni.c b/usr/src/lib/libdtrace_jni/common/dtrace_jni.c index 051db0f2af..4f68f6787e 100644 --- a/usr/src/lib/libdtrace_jni/common/dtrace_jni.c +++ b/usr/src/lib/libdtrace_jni/common/dtrace_jni.c @@ -84,7 +84,7 @@ * LocalConsumer itself. */ -#define DTRACE_JNI_VERSION 1 +#define DTRACE_JNI_VERSION 2 #define FIRST_HANDLE 0 /* sequence-generated consumer ID */ #define NO_HANDLE -1 diff --git a/usr/src/lib/libdtrace_jni/common/dtrace_jni.h b/usr/src/lib/libdtrace_jni/common/dtrace_jni.h index 7df12ce930..1366ac14b1 100644 --- a/usr/src/lib/libdtrace_jni/common/dtrace_jni.h +++ b/usr/src/lib/libdtrace_jni/common/dtrace_jni.h @@ -313,6 +313,7 @@ extern jmethodID g_pdataadd_jm; extern jmethodID g_pdataadd_rec_jm; extern jmethodID g_pdataadd_trace_jm; extern jmethodID g_pdataadd_stack_jm; +extern jmethodID g_pdataadd_symbol_jm; extern jmethodID g_pdataadd_printf_jm; extern jmethodID g_pdataadd_printa_jm; extern jmethodID g_pdatainvalidate_printa_jm; @@ -401,6 +402,20 @@ extern jmethodID g_distinit_jm; extern jclass g_ldist_jc; extern jmethodID g_ldistinit_jm; +/* KernelSymbolRecord */ +extern jclass g_symbol_jc; +extern jmethodID g_symbolinit_jm; +extern jmethodID g_symbolset_name_jm; + +/* UserSymbolRecord */ +extern jclass g_usymbol_jc; +extern jmethodID g_usymbolinit_jm; +extern jmethodID g_usymbolset_name_jm; + +/* ScalarRecord */ +extern jclass g_scalar_jc; +extern jmethodID g_scalarinit_jm; + /* * Populates the java class references and associated method and field IDs * declared in this file (above). diff --git a/usr/src/lib/libdtrace_jni/java/Makefile b/usr/src/lib/libdtrace_jni/java/Makefile index 774fa09034..14514ad857 100644 --- a/usr/src/lib/libdtrace_jni/java/Makefile +++ b/usr/src/lib/libdtrace_jni/java/Makefile @@ -125,6 +125,7 @@ API_CLASSNAMES=\ Flow \ InterfaceAttributes \ KernelStackRecord \ + KernelSymbolRecord \ LinearDistribution \ LocalConsumer \ LogDistribution \ @@ -148,8 +149,10 @@ API_CLASSNAMES=\ StackFrame \ StackValueRecord \ SumValue \ + SymbolValueRecord \ Tuple \ UserStackRecord \ + UserSymbolRecord \ Utility \ ValueRecord diff --git a/usr/src/lib/libdtrace_jni/java/docs/html/JavaDTraceAPI.html b/usr/src/lib/libdtrace_jni/java/docs/html/JavaDTraceAPI.html index 92bb4d641c..7696d167ed 100644 --- a/usr/src/lib/libdtrace_jni/java/docs/html/JavaDTraceAPI.html +++ b/usr/src/lib/libdtrace_jni/java/docs/html/JavaDTraceAPI.html @@ -185,11 +185,15 @@ <AREA HREF="../api/org/opensolaris/os/dtrace/ScalarRecord.html" ALT="ScalarRecord javadoc API" SHAPE=RECT - COORDS="364,333,477,375"> + COORDS="337,333,414,393"> <AREA HREF="../api/org/opensolaris/os/dtrace/StackValueRecord.html" ALT="StackValueRecord javadoc API" SHAPE=RECT - COORDS="487,333,633,375"> + COORDS="423,333,496,412"> + <AREA HREF="../api/org/opensolaris/os/dtrace/SymbolValueRecord.html" + ALT="SymbolValueRecord javadoc API" + SHAPE=RECT + COORDS="507,333,579,412"> <AREA HREF="../api/org/opensolaris/os/dtrace/SumValue.html" ALT="SumValue javadoc API" SHAPE=RECT diff --git a/usr/src/lib/libdtrace_jni/java/docs/html/fast.html b/usr/src/lib/libdtrace_jni/java/docs/html/fast.html index c820d77306..1f5104723c 100644 --- a/usr/src/lib/libdtrace_jni/java/docs/html/fast.html +++ b/usr/src/lib/libdtrace_jni/java/docs/html/fast.html @@ -517,7 +517,7 @@ action will not be included in the requested aggregate. The <a href="http://www.opensolaris.org/os/community/dtrace/"> OpenSolaris DTrace page</a> has links to resources to help you learn DTrace. In particular, you should read the <a -href="http://docs.sun.com/db/doc/817-6223"><i>Solaris Dynamic Tracing +href="http://docs.sun.com/app/docs/doc/817-6223"><i>Solaris Dynamic Tracing Guide</i></a>.<br> <br> Try the example Java programs on this page with other D scripts. You diff --git a/usr/src/lib/libdtrace_jni/java/docs/images/JavaDTraceAPI.gif b/usr/src/lib/libdtrace_jni/java/docs/images/JavaDTraceAPI.gif Binary files differindex 5583442ba5..433184fab3 100644 --- a/usr/src/lib/libdtrace_jni/java/docs/images/JavaDTraceAPI.gif +++ b/usr/src/lib/libdtrace_jni/java/docs/images/JavaDTraceAPI.gif diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelStackRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelStackRecord.java index 95b5fd2bd0..7e97c91ca4 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelStackRecord.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelStackRecord.java @@ -282,12 +282,13 @@ public final class KernelStackRecord implements StackValueRecord, } /** - * Compares this record with the given stack record. Compares the - * first unequal pair of bytes at the same index in each record's - * raw stack data, or if all corresponding bytes are equal, compares - * the length of each record's array of raw stack data. The {@code - * compareTo()} method is compatible with {@link #equals(Object o) - * equals()}. + * Compares this record with the given {@code KernelStackRecord}. + * Compares the first unequal pair of bytes at the same index in + * each record's raw stack data, or if all corresponding bytes are + * equal, compares the length of each record's array of raw stack + * data. Corresponding bytes are compared as unsigned values. The + * {@code compareTo()} method is compatible with {@link + * #equals(Object o) equals()}. * <p> * This implementation first checks if the specified record is this * {@code KernelStackRecord}. If so, it returns {@code 0}. @@ -302,17 +303,7 @@ public final class KernelStackRecord implements StackValueRecord, return 0; } - int len1 = rawStackData.length; - int len2 = r.rawStackData.length; - int cmp = 0; - for (int i = 0; (cmp == 0) && (i < len1) && (i < len2); ++i) { - cmp = ((rawStackData[i] < r.rawStackData[i]) ? -1 : - ((rawStackData[i] > r.rawStackData[i]) ? 1 : 0)); - } - if (cmp == 0) { - cmp = ((len1 < len2) ? -1 : ((len1 > len2) ? 1 : 0)); - } - return cmp; + return ProbeData.compareByteArrays(rawStackData, r.rawStackData); } private void diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelSymbolRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelSymbolRecord.java new file mode 100644 index 0000000000..7a32427ba4 --- /dev/null +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/KernelSymbolRecord.java @@ -0,0 +1,240 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * ident "%Z%%M% %I% %E% SMI" + */ +package org.opensolaris.os.dtrace; + +import java.io.*; +import java.beans.*; + +/** + * A value generated by the DTrace {@code mod()}, {@code func()}, or + * {@code sym()} action used to lookup the symbol associated with a + * kernel address. + * <p> + * Immutable. Supports persistence using {@link java.beans.XMLEncoder}. + * + * @author Tom Erickson + */ +public final class KernelSymbolRecord implements SymbolValueRecord, + Serializable, Comparable <KernelSymbolRecord> +{ + static final long serialVersionUID = -7156627773519296848L; + + static { + try { + BeanInfo info = Introspector.getBeanInfo(KernelSymbolRecord.class); + PersistenceDelegate persistenceDelegate = + new DefaultPersistenceDelegate( + new String[] {"symbol", "address"}) + { + /* + * Need to prevent DefaultPersistenceDelegate from using + * overridden equals() method, resulting in a + * StackOverFlowError. Revert to PersistenceDelegate + * implementation. See + * http://forum.java.sun.com/thread.jspa?threadID= + * 477019&tstart=135 + */ + protected boolean + mutatesTo(Object oldInstance, Object newInstance) + { + return (newInstance != null && oldInstance != null && + oldInstance.getClass() == newInstance.getClass()); + } + }; + BeanDescriptor d = info.getBeanDescriptor(); + d.setValue("persistenceDelegate", persistenceDelegate); + } catch (IntrospectionException e) { + e.printStackTrace(); + } + } + + /** @serial */ + private String symbol; // set natively after creation; treat as final + /** @serial */ + private final long address; + + /** + * Called by native code. + */ + private + KernelSymbolRecord(long addressValue) + { + address = addressValue; + } + + /** + * Creates a {@code KernelSymbolRecord} with the given symbol lookup + * and kernel address converted in probe context as a result of the + * DTrace {@code mod()}, {@code func()}, or {@code sym()} action. + * <p> + * Supports XML persistence. + * + * @param addressValue symbol address + * @param lookupValue the result in the native DTrace library of + * looking up the symbol associated with the given kernel address + * @throws NullPointerException if the given lookup value is {@code null} + */ + public + KernelSymbolRecord(String lookupValue, long addressValue) + { + symbol = lookupValue; + address = addressValue; + validate(); + } + + private void + validate() + { + if (symbol == null) { + throw new NullPointerException("symbol is null"); + } + } + + /** + * Gets the result of the address lookup in the same form returned + * by {@link Consumer#lookupKernelFunction(long address)}. + * + * @return non-null address lookup in the format defined by the + * native DTrace library + */ + public String + getSymbol() + { + return symbol; + } + + /** + * Called by native code and ProbeData addSymbolRecord() + */ + void + setSymbol(String lookupValue) + { + symbol = lookupValue; + validate(); + } + + /** + * Gets the symbol's kernel address. + * + * @return the symbol's kernel address + */ + public long + getAddress() + { + return address; + } + + /** + * Gets the symbol's kernel address. The value is used in {@link + * #equals(Object o) equals()} and {@link + * #compareTo(KernelSymbolRecord r) compareTo()} to test equality + * and to determine the natural ordering of {@code + * KernelSymbolRecord} instances. + * + * @return non-null value of the symbol's kernel address + */ + public Long + getValue() + { + return address; + } + + /** + * Compares the specified object with this {@code KernelSymbolRecord} + * for equality. Returns {@code true} if and only if the specified + * object is also a {@code KernelSymbolRecord} and both records have + * the same address. + * + * @return {@code true} if and only if the specified object is also + * a {@code KernelSymbolRecord} and both records have the same + * address + */ + @Override + public boolean + equals(Object o) + { + if (o instanceof KernelSymbolRecord) { + KernelSymbolRecord r = (KernelSymbolRecord)o; + return (address == r.address); + } + return false; + } + + /** + * Overridden to ensure that equal instances have equal hash codes. + */ + @Override + public int + hashCode() + { + return (int)(address ^ (address >>> 32)); + } + + /** + * Compares this record with the given kernel symbol lookup and + * orders by address. The comparison treats addresses as unsigned + * values so the ordering is consistent with that defined in the + * native DTrace library. The {@code compareTo()} method is + * compatible with {@link #equals(Object o) equals()}. + * + * @return -1, 0, or 1 as this record's address is less than, equal + * to, or greater than the given record's address + */ + public int + compareTo(KernelSymbolRecord r) + { + return ProbeData.compareUnsigned(address, r.address); + } + + private void + readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + // check class invariants + try { + validate(); + } catch (Exception e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + /** + * Gets the result of this symbol lookup. The format is defined in + * the native DTrace library and is as stable as that library + * definition. + * + * @return {@link #getSymbol()} + */ + @Override + public String + toString() + { + return symbol; + } +} diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LocalConsumer.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LocalConsumer.java index c6a1f41dad..dd453601e4 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LocalConsumer.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/LocalConsumer.java @@ -51,7 +51,7 @@ public class LocalConsumer implements Consumer { static Logger logger = Logger.getLogger(LocalConsumer.class.getName()); - private static final int DTRACE_JNI_VERSION = 1; + private static final int DTRACE_JNI_VERSION = 2; private static final Option[] DEFAULT_OPTIONS = new Option[] { new Option(Option.bufsize, Option.kb(256)), @@ -635,9 +635,22 @@ public class LocalConsumer implements Consumer { // that listeners finish executing consumerStopped() // before the stop() method returns. synchronized (this) { - state = State.STOPPED; - fireConsumerStopped(new ConsumerEvent(this, - System.nanoTime())); + if (state == State.STOPPED || state == state.CLOSED) { + // + // This consumer was stopped just after calling + // go() but before starting (the premature return + // case at the top of this work() method). It is + // possible to call close() on a consumer that has + // been stopped before starting. In that case the + // premature return above still takes us here in the + // finally clause, and we must not revert the CLOSED + // state to STOPPED. + // + } else { + state = State.STOPPED; + fireConsumerStopped(new ConsumerEvent(this, + System.nanoTime())); + } } // Notify the stop() method to stop waiting @@ -776,6 +789,8 @@ public class LocalConsumer implements Consumer { _stop(); } state = State.STOPPED; + fireConsumerStopped(new ConsumerEvent(this, + System.nanoTime())); } catch (DTraceException e) { if (exceptionHandler != null) { exceptionHandler.handleException(e); diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/PrintfRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/PrintfRecord.java index d7f5f45db6..cb2ee0cc16 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/PrintfRecord.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/PrintfRecord.java @@ -108,9 +108,9 @@ public final class PrintfRecord implements Record, Serializable { * @throws NullPointerException if o is null */ void - addUnformattedElement(Object o) + addUnformattedElement(ScalarRecord rec) { - records.add(new ScalarRecord(o)); + records.add(rec); } /** diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ProbeData.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ProbeData.java index a8978be334..a57b314c89 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ProbeData.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ProbeData.java @@ -111,7 +111,7 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { private Flow flow; // Scratch data, one element per native probedata->dtpda_edesc->dtepd_nrecs // element, cleared after records list is fully populated. - private transient List <Object> nativeElements; + private transient List <Record> nativeElements; /** @serial */ private List <Record> records; @@ -142,7 +142,7 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { cpu = cpuID; enabledProbeDescription = p; flow = f; - nativeElements = new ArrayList <Object> (nativeElementCount); + nativeElements = new ArrayList <Record> (nativeElementCount); records = new ArrayList <Record> (); validate(); } @@ -192,8 +192,11 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { } private void - addDataElement(Object o) + addDataElement(Record o) { + // Early error detection if native code adds the wrong type + Record r = Record.class.cast(o); + nativeElements.add(o); } @@ -217,9 +220,29 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { // assignment to a variable (results in a native probedata // record with no data). int len = nativeElements.size(); - Object o = null; - for (; ((o = nativeElements.get(i)) == null) && (i < len); ++i); - records.add(new ScalarRecord(o)); + Record rec = null; + for (; ((rec = nativeElements.get(i)) == null) && (i < len); ++i); + records.add(rec); + } + + /** + * Called by native code. + */ + private void + addSymbolRecord(int i, String lookupString) + { + int len = nativeElements.size(); + Record rec = null; + for (; ((rec = nativeElements.get(i)) == null) && (i < len); ++i); + SymbolValueRecord symbol = SymbolValueRecord.class.cast(rec); + if (symbol instanceof KernelSymbolRecord) { + KernelSymbolRecord.class.cast(symbol).setSymbol(lookupString); + } else if (symbol instanceof UserSymbolRecord) { + UserSymbolRecord.class.cast(symbol).setSymbol(lookupString); + } else { + throw new IllegalStateException("no symbol record at index " + i); + } + records.add(symbol); } /** @@ -229,14 +252,14 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { addStackRecord(int i, String framesString) { int len = nativeElements.size(); - Object o = null; - for (; ((o = nativeElements.get(i)) == null) && (i < len); ++i); - StackValueRecord stack = (StackValueRecord)o; + Record rec = null; + for (; ((rec = nativeElements.get(i)) == null) && (i < len); ++i); + StackValueRecord stack = StackValueRecord.class.cast(rec); StackFrame[] frames = KernelStackRecord.parse(framesString); if (stack instanceof KernelStackRecord) { - ((KernelStackRecord)stack).setStackFrames(frames); + KernelStackRecord.class.cast(stack).setStackFrames(frames); } else if (stack instanceof UserStackRecord) { - ((UserStackRecord)stack).setStackFrames(frames); + UserStackRecord.class.cast(stack).setStackFrames(frames); } else { throw new IllegalStateException("no stack record at index " + i); } @@ -270,7 +293,7 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { while (itr.hasPrevious() && (printa == null)) { record = itr.previous(); if (record instanceof PrintaRecord) { - printa = (PrintaRecord)record; + printa = PrintaRecord.class.cast(record); } } return printa; @@ -326,9 +349,10 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { addExitRecord(int i) { int len = nativeElements.size(); - Object o = null; - for (; ((o = nativeElements.get(i)) == null) && (i < len); ++i); - Integer exitStatus = (Integer)o; + Record rec = null; + for (; ((rec = nativeElements.get(i)) == null) && (i < len); ++i); + ScalarRecord scalar = ScalarRecord.class.cast(rec); + Integer exitStatus = Integer.class.cast(scalar.getValue()); records.add(new ExitRecord(exitStatus)); } @@ -342,8 +366,8 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { { Record record = records.get(records.size() - 1); if (record instanceof PrintfRecord) { - PrintfRecord printf = (PrintfRecord)record; - Object e; + PrintfRecord printf = PrintfRecord.class.cast(record); + Record e; for (int i = first; i <= last; ++i) { e = nativeElements.get(i); if (e == null) { @@ -354,7 +378,7 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { // record with no data). continue; } - printf.addUnformattedElement(e); + printf.addUnformattedElement(ScalarRecord.class.cast(e)); } } } @@ -376,7 +400,7 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { { Record record = records.get(records.size() - 1); if (record instanceof PrintfRecord) { - PrintfRecord printf = (PrintfRecord)record; + PrintfRecord printf = PrintfRecord.class.cast(record); printf.setFormattedString(s); } } @@ -416,8 +440,107 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { } } + static int + compareUnsigned(int i1, int i2) + { + int cmp; + + if (i1 < 0) { + if (i2 < 0) { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } else { + cmp = 1; // negative > positive + } + } else if (i2 < 0) { + cmp = -1; // positive < negative + } else { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } + + return cmp; + } + + static int + compareUnsigned(long i1, long i2) + { + int cmp; + + if (i1 < 0) { + if (i2 < 0) { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } else { + cmp = 1; // negative > positive + } + } else if (i2 < 0) { + cmp = -1; // positive < negative + } else { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } + + return cmp; + } + + static int + compareUnsigned(byte i1, byte i2) + { + int cmp; + + if (i1 < 0) { + if (i2 < 0) { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } else { + cmp = 1; // negative > positive + } + } else if (i2 < 0) { + cmp = -1; // positive < negative + } else { + cmp = (i1 < i2 ? -1 : (i1 > i2 ? 1 : 0)); + } + + return cmp; + } + + static int + compareByteArrays(byte[] a1, byte[] a2) + { + int cmp = 0; + int len1 = a1.length; + int len2 = a2.length; + + for (int i = 0; (cmp == 0) && (i < len1) && (i < len2); ++i) { + cmp = compareUnsigned(a1[i], a2[i]); + } + + if (cmp == 0) { + cmp = (len1 < len2 ? -1 : (len1 > len2 ? 1 : 0)); + } + + return cmp; + } + + @SuppressWarnings("unchecked") + static int + compareUnsigned(Comparable v1, Comparable v2) + { + int cmp; + + if (v1 instanceof Integer) { + int i1 = Integer.class.cast(v1); + int i2 = Integer.class.cast(v2); + cmp = compareUnsigned(i1, i2); + } else if (v1 instanceof Long) { + long i1 = Long.class.cast(v1); + long i2 = Long.class.cast(v2); + cmp = compareUnsigned(i1, i2); + } else { + cmp = v1.compareTo(v2); + } + + return cmp; + } + /** - * @throws ClassCastException if records or their data are are not + * @throws ClassCastException if records or their data are not * mutually comparable */ @SuppressWarnings("unchecked") @@ -428,15 +551,22 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { if (r1 instanceof ScalarRecord) { ScalarRecord t1 = ScalarRecord.class.cast(r1); ScalarRecord t2 = ScalarRecord.class.cast(r2); - Comparable v1 = Comparable.class.cast(t1.getValue()); - Comparable v2 = Comparable.class.cast(t2.getValue()); + Object o1 = t1.getValue(); + Object o2 = t2.getValue(); + if (o1 instanceof byte[]) { + byte[] a1 = byte[].class.cast(o1); + byte[] a2 = byte[].class.cast(o2); + cmp = compareByteArrays(a1, a2); + } else { + Comparable v1 = Comparable.class.cast(o1); + Comparable v2 = Comparable.class.cast(o2); + cmp = v1.compareTo(v2); // compare signed values + } + } else if (r1 instanceof Comparable) { + // StackValueRecord, SymbolValueRecord + Comparable v1 = Comparable.class.cast(r1); + Comparable v2 = Comparable.class.cast(r2); cmp = v1.compareTo(v2); - } else if (r1 instanceof PrintfRecord) { - PrintfRecord t1 = PrintfRecord.class.cast(r1); - PrintfRecord t2 = PrintfRecord.class.cast(r2); - String s1 = t1.toString(); - String s2 = t2.toString(); - cmp = s1.compareTo(s2); } else if (r1 instanceof ExitRecord) { ExitRecord e1 = ExitRecord.class.cast(r1); ExitRecord e2 = ExitRecord.class.cast(r2); @@ -444,8 +574,11 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { int status2 = e2.getStatus(); cmp = (status1 < status2 ? -1 : (status1 > status2 ? 1 : 0)); } else { - throw new IllegalArgumentException("Unexpected record type: " + - r1.getClass()); + // PrintfRecord, PrintaRecord + r1.getClass().cast(r2); + String s1 = r1.toString(); + String s2 = r2.toString(); + cmp = s1.compareTo(s2); } return cmp; @@ -673,10 +806,10 @@ public final class ProbeData implements Serializable, Comparable <ProbeData> { } record = records.get(i); if (record instanceof ValueRecord) { - value = ((ValueRecord)record).getValue(); + value = ValueRecord.class.cast(record).getValue(); if (value instanceof String) { buf.append("\""); - buf.append((String)value); + buf.append(String.class.cast(value)); buf.append("\""); } else { buf.append(record); diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ScalarRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ScalarRecord.java index 2654a07327..cbeafa34df 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ScalarRecord.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/ScalarRecord.java @@ -41,7 +41,7 @@ import java.beans.*; * @author Tom Erickson */ public final class ScalarRecord implements ValueRecord, Serializable { - static final long serialVersionUID = -34046471695050108L; + static final long serialVersionUID = -6920826443240176724L; static final int RAW_BYTES_INDENT = 5; static { @@ -49,7 +49,7 @@ public final class ScalarRecord implements ValueRecord, Serializable { BeanInfo info = Introspector.getBeanInfo(ScalarRecord.class); PersistenceDelegate persistenceDelegate = new DefaultPersistenceDelegate( - new String[] {"value"}) + new String[] {"value", "numberOfBytes"}) { /* * Need to prevent DefaultPersistenceDelegate from using @@ -75,20 +75,33 @@ public final class ScalarRecord implements ValueRecord, Serializable { /** @serial */ private final Object value; + /** @serial */ + private int numberOfBytes; /** - * Creates a scalar record with the given DTrace primitive. + * Creates a scalar record with the given DTrace primitive and the + * number of bytes used to store the primitive in the native DTrace + * buffer. Since traced 8- and 16-bit integers are promoted (as + * unsigned values) to 32-bit integers, it may be important for + * output formatting to know the number of bytes used to represent + * the primitive before promotion. * * @param v DTrace primitive data value - * @throws NullPointerException if the given value is null + * @param nativeByteCount number of bytes used to store the given + * primitive in the native DTrace buffer + * @throws NullPointerException if the given value is {@code null} + * @throws IllegalArgumentException if the given number of bytes is + * not consistent with the given primitive type or is not greater + * than zero * @throws ClassCastException if the given value is not a DTrace * primitive type listed as a possible return value of {@link * #getValue()} */ public - ScalarRecord(Object v) + ScalarRecord(Object v, int nativeByteCount) { value = v; + numberOfBytes = nativeByteCount; validate(); } @@ -98,12 +111,47 @@ public final class ScalarRecord implements ValueRecord, Serializable { if (value == null) { throw new NullPointerException(); } + // Short-circuit-evaluate common cases first - if (!((value instanceof Number) || - (value instanceof String) || - (value instanceof byte[]))) { - throw new ClassCastException("value is not a D primitive"); - } + if (value instanceof Integer) { + switch (numberOfBytes) { + case 1: + case 2: + case 4: + break; + default: + throw new IllegalArgumentException( + "number of bytes is " + numberOfBytes + + ", expected 1, 2, or 4 for Integer primitive"); + } + } else if (value instanceof Long) { + if (numberOfBytes != 8) { + throw new IllegalArgumentException( + "number of bytes is " + numberOfBytes + + ", expected 8 for Long primitive"); + } + } else if ((value instanceof String) || (value instanceof byte[])) { + switch (numberOfBytes) { + case 1: + case 2: + case 4: + case 8: + throw new IllegalArgumentException( + "number of bytes is " + numberOfBytes + + ", expected a number other than " + + "1, 2, 4, or 8 for String or byte-array " + + "primitive"); + } + } else if (value instanceof Number) { + if (numberOfBytes <= 0) { + throw new IllegalArgumentException( + "number of bytes is " + numberOfBytes + + ", must be greater than zero"); + } + } else { + throw new ClassCastException(value.getClass().getName() + + " value is not a D primitive"); + } } /** @@ -123,6 +171,24 @@ public final class ScalarRecord implements ValueRecord, Serializable { } /** + * Gets the number of bytes used to store the primitive value of + * this record in the native DTrace buffer. Since traced 8- and + * 16-bit integers are promoted (as unsigned values) to 32-bit + * integers, it may be important for output formatting to know the + * number of bytes used to represent the primitive before promotion. + * + * @return the number of bytes used to store the primitive value + * of this record in the native DTrace buffer, guaranteed to be + * greater than zero and consisitent with the type of the primitive + * value + */ + public int + getNumberOfBytes() + { + return numberOfBytes; + } + + /** * Compares the specified object with this record for equality. * Defines equality as having the same value. * diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/SymbolValueRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/SymbolValueRecord.java new file mode 100644 index 0000000000..04ee1842c0 --- /dev/null +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/SymbolValueRecord.java @@ -0,0 +1,52 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * ident "%Z%%M% %I% %E% SMI" + */ +package org.opensolaris.os.dtrace; + +/** + * A value generated by the DTrace {@code mod()}, {@code func()}, {@code + * sym()}, {@code umod()}, {@code ufunc()} or {@code usym()} action used + * to lookup the symbol associated with an address in probe context. + * + * @author Tom Erickson + */ +public interface SymbolValueRecord extends ValueRecord { + /** + * Gets the result of the address lookup. + * + * @return non-null address lookup in the format defined by the + * native DTrace library + */ + public String getSymbol(); + + /** + * Gets the symbol address. + * + * @return the symbol address + */ + public long getAddress(); +} diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/Tuple.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/Tuple.java index 65743e657f..6959c1eadb 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/Tuple.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/Tuple.java @@ -154,17 +154,13 @@ public final class Tuple implements Serializable, Comparable <Tuple>, * {@link ScalarRecord#getValue()} */ private void - addElement(Object element) + addElement(ValueRecord element) { if (element == null) { throw new NullPointerException("tuple element is null at " + "index " + elements.size()); } - if (element instanceof ValueRecord) { - elements.add(ValueRecord.class.cast(element)); - } else { - elements.add(new ScalarRecord(element)); - } + elements.add(element); } /** @@ -269,24 +265,34 @@ public final class Tuple implements Serializable, Comparable <Tuple>, // lenient sort does not throw exceptions @SuppressWarnings("unchecked") - private int + private static int compareObjects(Object o1, Object o2) { int cmp; - Class c1 = o1.getClass(); - Class c2 = o2.getClass(); - if (c1.isAssignableFrom(c2) && (o1 instanceof Comparable)) { - Comparable c = Comparable.class.cast(o1); - cmp = c.compareTo(c1.cast(o2)); + + if (o1 instanceof Comparable) { + Class c1 = o1.getClass(); + Class c2 = o2.getClass(); + if (c1.equals(c2)) { + cmp = ProbeData.compareUnsigned(Comparable.class.cast(o1), + Comparable.class.cast(o2)); + } else { + // Compare string values. + String s1 = o1.toString(); + String s2 = o2.toString(); + cmp = s1.compareTo(s2); + } + } else if (o1 instanceof byte[] && o2 instanceof byte[]) { + byte[] a1 = byte[].class.cast(o1); + byte[] a2 = byte[].class.cast(o2); + cmp = ProbeData.compareByteArrays(a1, a2); } else { - // Compare string values. If matching, compare object class. + // Compare string values. String s1 = o1.toString(); String s2 = o2.toString(); cmp = s1.compareTo(s2); - if (cmp == 0) { - cmp = c1.getName().compareTo(c2.getName()); - } } + return cmp; } @@ -297,13 +303,13 @@ public final class Tuple implements Serializable, Comparable <Tuple>, * of corresponding elements and comparing subsequent pairs only * when all previous pairs are equal (as a tie breaker). If * corresponding elements are not mutually comparable, it compares - * the string values of those elements, then if the string values - * are equal, it compares the class names of those elements' types. - * If all corresponding elements are equal, then the tuple with more - * elements sorts higher than the tuple with fewer elements. + * the string values of those elements. If all corresponding + * elements are equal, then the tuple with more elements sorts + * higher than the tuple with fewer elements. * * @return a negative integer, zero, or a postive integer as this * tuple is less than, equal to, or greater than the given tuple + * @see Tuple#compare(Tuple t1, Tuple t2, int pos) */ public int compareTo(Tuple t) @@ -311,24 +317,8 @@ public final class Tuple implements Serializable, Comparable <Tuple>, int cmp = 0; int len = size(); int tlen = t.size(); - ValueRecord rec; - ValueRecord trec; - Object val; - Object tval; for (int i = 0; (cmp == 0) && (i < len) && (i < tlen); ++i) { - rec = get(i); - trec = t.get(i); - if (rec instanceof ScalarRecord) { - val = rec.getValue(); - } else { - val = rec; - } - if (trec instanceof ScalarRecord) { - tval = trec.getValue(); - } else { - tval = trec; - } - cmp = compareObjects(val, tval); + cmp = Tuple.compare(this, t, i); } if (cmp == 0) { cmp = (len < tlen ? -1 : (len > tlen ? 1 : 0)); @@ -336,6 +326,43 @@ public final class Tuple implements Serializable, Comparable <Tuple>, return cmp; } + /** + * Compares corresponding tuple elements at the given zero-based + * index. Elements are ordered as defined in the native DTrace + * library, which treats integer values as unsigned when sorting. + * + * @param t1 first tuple + * @param t2 second tuple + * @param pos nth tuple element, starting at zero + * @return a negative integer, zero, or a postive integer as the + * element in the first tuple is less than, equal to, or greater + * than the element in the second tuple + * @throws IndexOutOfBoundsException if the given tuple index {@code + * pos} is out of range {@code (pos < 0 || pos >= size())} for + * either of the given tuples + */ + public static int + compare(Tuple t1, Tuple t2, int pos) + { + int cmp = 0; + ValueRecord rec1 = t1.get(pos); + ValueRecord rec2 = t2.get(pos); + Object val1; + Object val2; + if (rec1 instanceof ScalarRecord) { + val1 = rec1.getValue(); + } else { + val1 = rec1; + } + if (rec2 instanceof ScalarRecord) { + val2 = rec2.getValue(); + } else { + val2 = rec2; + } + cmp = compareObjects(val1, val2); + return (cmp); + } + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserStackRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserStackRecord.java index 7c6e64872b..838beb4b83 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserStackRecord.java +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserStackRecord.java @@ -216,12 +216,7 @@ public final class UserStackRecord implements StackValueRecord, } if (o instanceof UserStackRecord) { UserStackRecord r = (UserStackRecord)o; - // raw stack data includes the process ID, but the process - // ID passed to the constructor is not validated against the - // raw stack data; probably best for this class to test all - // of its state without making assumptions - return ((processID == r.processID) && - stackRecord.equals(r.stackRecord)); + return stackRecord.equals(r.stackRecord); } return false; } @@ -233,21 +228,23 @@ public final class UserStackRecord implements StackValueRecord, public int hashCode() { - return (stackRecord.hashCode() + processID); + return stackRecord.hashCode(); } /** * Compares this record with the given {@code UserStackRecord}. - * Compares process ID first, then if those are equal, compares the - * views returned by {@link #asKernelStackRecord()}. The {@code - * compareTo()} method is compatible with {@link #equals(Object o) - * equals()}. + * Compares the first unequal pair of bytes at the same index in + * each record's raw stack data, or if all corresponding bytes are + * equal, compares the length of each record's array of raw stack + * data. Corresponding bytes are compared as unsigned values. The + * {@code compareTo()} method is compatible with {@link + * #equals(Object o) equals()}. * <p> * This implementation first checks if the specified object is this * {@code UserStackRecord}. If so, it returns {@code 0}. * - * @return -1, 0, or 1 as this record is less than, equal to, or - * greater than the given record + * @return -1, 0, or 1 as this record's raw stack data is less than, + * equal to, or greater than the given record's raw stack data */ public int compareTo(UserStackRecord r) @@ -256,13 +253,7 @@ public final class UserStackRecord implements StackValueRecord, return 0; } - int cmp = 0; - cmp = ((processID < r.processID) ? -1 : - ((processID > r.processID) ? 1 : 0)); - if (cmp == 0) { - cmp = stackRecord.compareTo(r.stackRecord); - } - return cmp; + return stackRecord.compareTo(r.stackRecord); } /** diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserSymbolRecord.java b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserSymbolRecord.java new file mode 100644 index 0000000000..b53eddef2f --- /dev/null +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/UserSymbolRecord.java @@ -0,0 +1,469 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * ident "%Z%%M% %I% %E% SMI" + */ +package org.opensolaris.os.dtrace; + +import java.io.*; +import java.beans.*; + +/** + * A value generated by the DTrace {@code umod()}, {@code ufunc()}, or + * {@code usym()} action used to lookup the symbol associated with a + * user address. + * <p> + * Immutable. Supports persistence using {@link java.beans.XMLEncoder}. + * + * @author Tom Erickson + */ +public final class UserSymbolRecord implements SymbolValueRecord, + Serializable, Comparable <UserSymbolRecord> +{ + static final long serialVersionUID = -591954442654439794L; + + static { + try { + BeanInfo info = Introspector.getBeanInfo(UserSymbolRecord.class); + PersistenceDelegate persistenceDelegate = + new DefaultPersistenceDelegate( + new String[] {"processID", "symbol", "address"}) + { + /* + * Need to prevent DefaultPersistenceDelegate from using + * overridden equals() method, resulting in a + * StackOverFlowError. Revert to PersistenceDelegate + * implementation. See + * http://forum.java.sun.com/thread.jspa?threadID= + * 477019&tstart=135 + */ + protected boolean + mutatesTo(Object oldInstance, Object newInstance) + { + return (newInstance != null && oldInstance != null && + oldInstance.getClass() == newInstance.getClass()); + } + }; + BeanDescriptor d = info.getBeanDescriptor(); + d.setValue("persistenceDelegate", persistenceDelegate); + } catch (IntrospectionException e) { + e.printStackTrace(); + } + } + + // serialized explicitly to hide implementation; treat as final + private transient Value value; + // set natively after creation; treat as final + private transient String symbol; + + /** + * Called by native code. + */ + private + UserSymbolRecord(int pid, long addressValue) + { + value = new Value(pid, addressValue); + } + + /** + * Creates a {@code UserSymbolRecord} with the given process ID, + * symbol lookup, and user address converted in probe context as a + * result of the DTrace {@code umod()}, {@code ufunc()}, or {@code + * usym()} action. + * <p> + * Supports XML persistence. + * + * @param pid non-negative user process ID + * @param lookupValue the result in the native DTrace library of + * looking up the symbol associated with the given user address + * @param addressValue symbol address + * @throws NullPointerException if the given lookup value is {@code null} + * @throws IllegalArgumentException if the given process ID is + * negative + */ + public + UserSymbolRecord(int pid, String lookupValue, long addressValue) + { + value = new Value(pid, addressValue); + symbol = lookupValue; + validate(); + } + + private void + validate() + { + if (symbol == null) { + throw new NullPointerException("symbol is null"); + } + } + + /** + * Gets the process ID associated with this record's symbol. + * + * @return non-negative pid + */ + public int + getProcessID() + { + return value.getProcessID(); + } + + /** + * Gets the result of the address lookup in the same form returned + * by {@link Consumer#lookupUserFunction(int pid, long address)}. + * + * @return non-null address lookup in the format defined by the + * native DTrace library + */ + public String + getSymbol() + { + return symbol; + } + + /** + * Called by native code and ProbeData addSymbolRecord() + */ + void + setSymbol(String lookupValue) + { + symbol = lookupValue; + validate(); + } + + /** + * Gets the symbol's user address. + * + * @return the symbol's user address + */ + public long + getAddress() + { + return value.getAddress(); + } + + /** + * Gets the composite value of the symbol's process ID and address. + * The value is used in {@link #equals(Object o) equals()} and + * {@link #compareTo(UserSymbolRecord r) compareTo()} to test + * equality and to determine the natural ordering of {@code + * UserSymbolRecord} instances. + * + * @return non-null composite value of the symbols's process ID and + * address + */ + public Value + getValue() + { + return value; + } + + /** + * Compares the specified object with this {@code UserSymbolRecord} + * for equality. Returns {@code true} if and only if the specified + * object is also a {@code UserSymbolRecord} and both records have + * the same process ID and the same address. + * + * @return {@code true} if and only if the specified object is also + * a {@code UserSymbolRecord} and both records have the same + * process ID and the same address + */ + @Override + public boolean + equals(Object o) + { + if (o instanceof UserSymbolRecord) { + UserSymbolRecord r = (UserSymbolRecord)o; + return value.equals(r.value); + } + return false; + } + + /** + * Overridden to ensure that equal instances have equal hash codes. + */ + @Override + public int + hashCode() + { + return value.hashCode(); + } + + /** + * Compares this record with the given user symbol lookup and orders + * by the combined value of process ID first and address second. + * The comparison treats addresses as unsigned values so the + * ordering is consistent with that defined in the native DTrace + * library. The {@code compareTo()} method is compatible with {@link + * #equals(Object o) equals()}. + * + * @return -1, 0, or 1 as this record's combined process ID and + * address is less than, equal to, or greater than the given + * record's combined process ID and address + */ + public int + compareTo(UserSymbolRecord r) + { + return value.compareTo(r.value); + } + + /** + * Serialize this {@code UserSymbolRecord} instance. + * + * @serialData processID ({@code int}), followed by symbol ({@code + * java.lang.String}), followed by address ({@code long}) + */ + private void + writeObject(ObjectOutputStream s) throws IOException + { + s.defaultWriteObject(); + s.writeInt(getProcessID()); + s.writeObject(getSymbol()); + s.writeLong(getAddress()); + } + + private void + readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + int pid = s.readInt(); + symbol = (String)s.readObject(); + long addressValue = s.readLong(); + try { + value = new Value(pid, addressValue); + validate(); + } catch (Exception e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + /** + * Gets the result of this symbol lookup. The format is defined in + * the native DTrace library and is as stable as that library + * definition. + * + * @return {@link #getSymbol()} + */ + @Override + public String + toString() + { + return symbol; + } + + /** + * The composite value of a symbol's process ID and user address. + * <p> + * Immutable. Supports persistence using {@link + * java.beans.XMLEncoder}. + */ + public static final class Value implements Serializable, + Comparable <Value> { + static final long serialVersionUID = -91449037747641135L; + + static { + try { + BeanInfo info = Introspector.getBeanInfo( + UserSymbolRecord.Value.class); + PersistenceDelegate persistenceDelegate = + new DefaultPersistenceDelegate( + new String[] {"processID", "address"}) + { + /* + * Need to prevent DefaultPersistenceDelegate from using + * overridden equals() method, resulting in a + * StackOverFlowError. Revert to PersistenceDelegate + * implementation. See + * http://forum.java.sun.com/thread.jspa?threadID= + * 477019&tstart=135 + */ + protected boolean + mutatesTo(Object oldInstance, Object newInstance) + { + return (newInstance != null && oldInstance != null && + oldInstance.getClass() == + newInstance.getClass()); + } + }; + BeanDescriptor d = info.getBeanDescriptor(); + d.setValue("persistenceDelegate", persistenceDelegate); + } catch (IntrospectionException e) { + e.printStackTrace(); + } + } + + /** @serial */ + private final int processID; + /** @serial */ + private final long address; + + /** + * Creates a composite value with the given user process ID and + * symbol address. + * <p> + * Supports XML persistence. + * + * @param pid non-negative process ID + * @param addressValue symbol address + * @throws IllegalArgumentException if the given process ID is + * negative + */ + public + Value(int pid, long addressValue) + { + processID = pid; + address = addressValue; + validate(); + } + + private void + validate() + { + if (processID < 0) { + throw new IllegalArgumentException("process ID is negative"); + } + } + + /** + * Gets the process ID associated with this value's user + * address. + * + * @return non-negative pid + */ + public int + getProcessID() + { + return processID; + } + + /** + * Gets the symbol's user address. + * + * @return the symbol's user address + */ + public long + getAddress() + { + return address; + } + + /** + * Compares the specified object with this {@code + * UserSymbolRecord.Value} for equality. Returns {@code true} + * if and only if the specified object is also a {@code + * UserSymbolRecord.Value} and both values have the same process + * ID and the same address. + * + * @return {@code true} if and only if the specified object is + * also a {@code UserSymbolRecord.Value} and both values have + * the same process ID and the same address + */ + @Override + public boolean + equals(Object o) + { + if (o instanceof Value) { + Value v = (Value)o; + return ((processID == v.processID) && (address == v.address)); + } + return false; + } + + /** + * Overridden to ensure that equal instances have equal hash + * codes. + */ + @Override + public int + hashCode() + { + int hash = 17; + hash = 37 * hash + processID; + hash = 37 * hash + (int)(address ^ (address >>> 32)); + return hash; + } + + /** + * Compares this value with the given {@code + * UserSymbolRecord.Value} and orders by process ID first and + * address second. The comparison treats addresses as unsigned + * values so the ordering is consistent with that defined in the + * native DTrace library. The {@code compareTo()} method is + * compatible with {@link #equals(Object o) equals()}. + * + * @return -1, 0, or 1 as this value's combined process ID and + * address is less than, equal to, or greater than the given + * value's combined process ID and address + */ + public int + compareTo(Value v) + { + int cmp; + cmp = (processID < v.processID ? -1 : + (processID > v.processID ? 1 : 0)); + if (cmp == 0) { + cmp = ProbeData.compareUnsigned(address, v.address); + } + return cmp; + } + + private void + readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + // check class invariants + try { + validate(); + } catch (Exception e) { + throw new InvalidObjectException(e.getMessage()); + } + } + + /** + * Gets a string representation of this {@code + * UserSymbolRecord.Value} instance useful for logging and not + * intended for display. The exact details of the + * representation are unspecified and subject to change, but the + * following format may be regarded as typical: + * <pre><code> + * class-name[property1 = value1, property2 = value2] + * </code></pre> + */ + public String + toString() + { + StringBuilder buf = new StringBuilder(); + buf.append(Value.class.getName()); + buf.append("[processID = "); + buf.append(processID); + buf.append(", address = "); + buf.append(address); + buf.append(']'); + return buf.toString(); + } + } +} diff --git a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/package.html b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/package.html index 92689cf5f2..9ca357a440 100644 --- a/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/package.html +++ b/usr/src/lib/libdtrace_jni/java/src/org/opensolaris/os/dtrace/package.html @@ -47,7 +47,7 @@ end commented-out block --> For overviews, tutorials, examples, guides, and tool documentation, please see: <br><br> -<a href="http://docs.sun.com/db/doc/817-6223"> +<a href="http://docs.sun.com/app/docs/doc/817-6223"> <i>Solaris Dynamic Tracing Guide</i></a><br> <a href="http://www.opensolaris.org/os/community/dtrace"> OpenSolaris DTrace Website</a><br> diff --git a/usr/src/pkgdefs/SUNWdtrc/prototype_doc b/usr/src/pkgdefs/SUNWdtrc/prototype_doc index 520b6184f7..d79313545b 100644 --- a/usr/src/pkgdefs/SUNWdtrc/prototype_doc +++ b/usr/src/pkgdefs/SUNWdtrc/prototype_doc @@ -69,6 +69,7 @@ f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/Interface f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/InterfaceAttributes.Stability.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/InterfaceAttributes.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/KernelStackRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/KernelSymbolRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/LinearDistribution.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/LocalConsumer.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/LogDistribution.html 0644 root other @@ -93,9 +94,12 @@ f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/Record.ht f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/ScalarRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/StackFrame.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/StackValueRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/SymbolValueRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/SumValue.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/Tuple.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/UserStackRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/UserSymbolRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/UserSymbolRecord.Value.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/ValueRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/package-frame.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/package-summary.html 0644 root other @@ -130,6 +134,7 @@ f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/InterfaceAttributes.Stability.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/InterfaceAttributes.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/KernelStackRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/KernelSymbolRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/LinearDistribution.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/LocalConsumer.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/LogDistribution.html 0644 root other @@ -154,9 +159,12 @@ f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/ScalarRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/StackFrame.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/StackValueRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/SymbolValueRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/SumValue.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/Tuple.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/UserStackRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/UserSymbolRecord.html 0644 root other +f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/UserSymbolRecord.Value.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/class-use/ValueRecord.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/org/opensolaris/os/dtrace/package-use.html 0644 root other f none usr/share/lib/java/javadoc/dtrace/api/package-list 0644 root other |