fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER START
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The contents of this file are subject to the terms of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Common Development and Distribution License (the "License").
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You may not use this file except in compliance with the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * or http://www.opensolaris.org/os/licensing.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * See the License for the specific language governing permissions
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and limitations under the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * When distributing Covered Code, include this CDDL HEADER in each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If applicable, add the following below this CDDL HEADER, with the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * fields enclosed by brackets "[]" replaced with your own identifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * information: Portions Copyright [yyyy] [name of copyright owner]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER END
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
e77b06d21580f630e0a7c437495ab283d3672828tomee * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use is subject to license terms.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <stdio.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <ctype.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <limits.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <errno.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <stdlib.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <unistd.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <strings.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <sys/wait.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <limits.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <signal.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <libproc.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <pthread.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee#include <dtrace_jni.h>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Implements the work done in the running consumer loop. The native Java
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * methods (JNI layer) are implemented in dtrace_jni.c.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Record handler passed to dtrace_work() */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_chewrec(const dtrace_probedata_t *, const dtrace_recdesc_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Probe data handler passed to dtrace_work() */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_chew(const dtrace_probedata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Processes requests from LocalConsumer enqueued during dtrace_sleep() */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic dtj_status_t dtj_process_requests(dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Callback handlers set in dtj_set_callback_handlers(), called from libdtrace
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * in the consumer loop (from dtrace_work())
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_drophandler(const dtrace_dropdata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_errhandler(const dtrace_errdata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic void dtj_prochandler(struct ps_prochandle *, const char *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_setopthandler(const dtrace_setoptdata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Buffered output handler called from libdtrace in both the consumer loop (from
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_work()) and the get_aggregate() function (from
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_aggregate_print()).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_bufhandler(const dtrace_bufdata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Conversion of libdtrace data into Java Objects */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_recdata(dtj_java_consumer_t *, uint32_t, caddr_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_bytedata(JNIEnv *, uint32_t, caddr_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_new_stack_record(const caddr_t, const dtrace_recdesc_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_new_probedata_stack_record(const dtrace_probedata_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *, dtj_java_consumer_t *);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject dtj_new_symbol_record(const caddr_t, const dtrace_recdesc_t *,
127bbe13a6d36580af6a8ded154f1201a6250772tomee dtj_java_consumer_t *);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject dtj_new_probedata_symbol_record(const dtrace_probedata_t *,
127bbe13a6d36580af6a8ded154f1201a6250772tomee const dtrace_recdesc_t *, dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Aggregation data */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_new_tuple_stack_record(const dtrace_aggdata_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *, const char *, dtj_java_consumer_t *);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject dtj_new_tuple_symbol_record(const dtrace_aggdata_t *,
127bbe13a6d36580af6a8ded154f1201a6250772tomee const dtrace_recdesc_t *, const char *, dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_new_distribution(const dtrace_aggdata_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *, dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject dtj_new_aggval(dtj_java_consumer_t *, const dtrace_aggdata_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t dtj_average(caddr_t, uint64_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t dtj_avg_total(caddr_t, uint64_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t dtj_avg_count(caddr_t);
e77b06d21580f630e0a7c437495ab283d3672828tomeestatic jobject dtj_stddev(JNIEnv *, caddr_t, uint64_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Aggregation functions */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic void dtj_aggwalk_init(dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_agghandler(const dtrace_bufdata_t *, dtj_java_consumer_t *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic boolean_t dtj_is_included(const dtrace_aggdata_t *,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic void dtj_attach_frames(dtj_java_consumer_t *, jobject, jobjectArray);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic void dtj_attach_name(dtj_java_consumer_t *, jobject, jstring);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic boolean_t dtj_is_stack_action(dtrace_actkind_t);
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic boolean_t dtj_is_symbol_action(dtrace_actkind_t);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int dtj_clear(const dtrace_aggdata_t *, void *);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The consumer loop needs to protect calls to libdtrace functions with a global
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * lock. JNI native method calls in dtrace_jni.c are already protected and do
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * not need this function.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_status_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_get_dtrace_error(dtj_java_consumer_t *jc, dtj_error_t *e)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_hdl_t *dtp = jc->dtjj_consumer->dtjc_dtp;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* Must not call MonitorEnter with a pending exception */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee if ((*jenv)->ExceptionCheck(jenv)) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee WRAP_EXCEPTION(jenv);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee return (DTJ_ERR);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Grab global lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorEnter(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee e->dtje_number = dtrace_errno(dtp);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee e->dtje_message = dtrace_errmsg(dtp, e->dtje_number);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Protected by global lock (LocalConsumer.class) that protects call to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Java_org_opensolaris_os_dtrace_LocalConsumer__1go()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_status_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_set_callback_handlers(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_hdl_t *dtp = jc->dtjj_consumer->dtjc_dtp;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_optval_t optval;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_handle_buffered(dtp, &dtj_bufhandler, NULL) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to establish buffered handler: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_handle_drop(dtp, &dtj_drophandler, NULL) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to establish drop handler: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_handle_err(dtp, &dtj_errhandler, NULL) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to establish error handler: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_handle_proc(dtp, &dtj_prochandler, NULL) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to establish proc handler: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_getopt(dtp, "flowindent", &optval) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "couldn't get option %s: %s", "flowindent",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_flow = (optval != DTRACEOPT_UNSET);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_handle_setopt(dtp, &dtj_setopthandler, NULL) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to establish setopt handler: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(dtp, dtrace_errno(dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* ARGSUSED */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_drophandler(const dtrace_dropdata_t *data, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *dropkind;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring msg = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring kind = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject drop = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc = pthread_getspecific(g_dtj_consumer_key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee msg = dtj_NewStringNative(jenv, data->dtdda_msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (data->dtdda_kind) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_PRINCIPAL:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "PRINCIPAL";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_AGGREGATION:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "AGGREGATION";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_DYNAMIC:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "DYNAMIC";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_DYNRINSE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "DYNRINSE";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_DYNDIRTY:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "DYNDIRTY";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_SPEC:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "SPEC";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_SPECBUSY:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "SPECBUSY";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_SPECUNAVAIL:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "SPECUNAVAIL";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_STKSTROVERFLOW:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "STKSTROVERFLOW";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEDROP_DBLERROR:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "DBLERROR";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dropkind = "UNKNOWN";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee kind = (*jenv)->NewStringUTF(jenv, dropkind);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee drop = (*jenv)->NewObject(jenv, g_drop_jc, g_dropinit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee data->dtdda_cpu, kind, data->dtdda_drops, data->dtdda_total, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, kind);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller, g_drop_jm, drop);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, drop);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* ARGSUSED */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_errhandler(const dtrace_errdata_t *data, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *f;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject probe = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring fault = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring msg = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject error = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc = pthread_getspecific(g_dtj_consumer_key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee probe = dtj_new_probedesc(jc, data->dteda_pdesc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!probe) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee f = dtj_get_fault_name(data->dteda_fault);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (f) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fault = (*jenv)->NewStringUTF(jenv, f);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, probe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (data->dteda_fault) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEFLT_BADADDR:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEFLT_BADALIGN:
b8fac8e162eda7e98db13dfa3e439e43f90f41d9jhaslam case DTRACEFLT_BADSTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addr = data->dteda_addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addr = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee msg = dtj_NewStringNative(jenv, data->dteda_msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, probe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, fault);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee error = (*jenv)->NewObject(jenv, g_error_jc, g_errinit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee probe,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee data->dteda_edesc->dtepd_epid,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee data->dteda_cpu,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee data->dteda_action,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee data->dteda_offset,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee fault, addr, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, fault);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, probe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller, g_error_jm, error);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, error);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Since the function signature does not allow us to return an abort signal, we
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * need to temporarily clear any pending exception before returning, since
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * without the abort we can't guarantee that the exception will be checked in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * time to prevent invalid JNI function calls.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* ARGSUSED */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_prochandler(struct ps_prochandle *P, const char *msg, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const psinfo_t *prp = Ppsinfo(P);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int pid = Pstatus(P)->pr_pid;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int signal = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee char signame[SIG2STR_MAX];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *statusname;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int exit = INT_MAX; /* invalid initial status */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring status = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring signalName = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring message = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject process = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc = pthread_getspecific(g_dtj_consumer_key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (Pstate(P)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case PS_RUN:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee statusname = "RUN";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case PS_STOP:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee statusname = "STOP";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case PS_UNDEAD:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee statusname = "UNDEAD";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (prp != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee exit = WEXITSTATUS(prp->pr_wstat);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee signal = WTERMSIG(prp->pr_wstat);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (void) proc_signame(signal, signame, sizeof (signame));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee signalName = (*jenv)->NewStringUTF(jenv, signame);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto proc_end;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ++jc->dtjj_consumer->dtjc_procs_ended;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case PS_LOST:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee statusname = "LOST";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ++jc->dtjj_consumer->dtjc_procs_ended;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case PS_DEAD:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * PS_DEAD not handled by dtrace.c prochandler, still this is a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * case of process termination and it can't hurt to handle it.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee statusname = "DEAD";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ++jc->dtjj_consumer->dtjc_procs_ended;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Unexpected, but erring on the side of tolerance by not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * crashing the consumer. Failure to notify listeners of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * process state not handled by the dtrace.c prochandler does
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * not seem serious.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee status = (*jenv)->NewStringUTF(jenv, statusname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, signalName);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto proc_end;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (msg) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee message = dtj_NewStringNative(jenv, msg);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!message) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, status);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, signalName);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto proc_end;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee process = (*jenv)->NewObject(jenv, g_process_jc, g_procinit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pid, status, signal, signalName, NULL, message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, status);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, signalName);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto proc_end;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (exit != INT_MAX) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* valid exit status */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, process, g_procexit_jm, exit);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, process);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto proc_end;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller, g_proc_jm, process);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, process);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeproc_end:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Save the exception so we can rethrow it later when it's safe.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jc->dtjj_exception) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jthrowable e = (*jenv)->ExceptionOccurred(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_exception = e;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->ExceptionClear(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* ARGSUSED */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_setopthandler(const dtrace_setoptdata_t *data, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc = pthread_getspecific(g_dtj_consumer_key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (strcmp(data->dtsda_option, "flowindent") == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_flow =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (data->dtsda_newval != DTRACEOPT_UNSET);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Most of this function lifted from libdtrace/common/dt_consume.c
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dt_print_bytes().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_bytedata(JNIEnv *jenv, uint32_t nbytes, caddr_t addr)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If the byte stream is a series of printable characters, followed by
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * a terminating byte, we print it out as a string. Otherwise, we
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * assume that it's something else and just print the bytes.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int i, j;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee char *c = addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jobj = NULL; /* return value */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (nbytes == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return ((*jenv)->NewStringUTF(jenv, ""));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (i = 0; i < nbytes; i++) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * We define a "printable character" to be one for which
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * isprint(3C) returns non-zero, isspace(3C) returns non-zero,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * or a character which is either backspace or the bell.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Backspace and the bell are regrettably special because
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * they fail the first two tests -- and yet they are entirely
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * printable. These are the only two control characters that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * have meaning for the terminal and for which isprint(3C) and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * isspace(3C) return 0.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (isprint(c[i]) || isspace(c[i]) ||
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee c[i] == '\b' || c[i] == '\a')
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee continue;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (c[i] == '\0' && i > 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This looks like it might be a string. Before we
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * assume that it is indeed a string, check the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * remainder of the byte range; if it contains
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * additional non-nul characters, we'll assume that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * it's a binary stream that just happens to look like
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * a string.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (j = i + 1; j < nbytes; j++) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (c[j] != '\0')
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (j != nbytes)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* It's a string */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (dtj_NewStringNative(jenv, (char *)addr));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (i == nbytes) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The byte range is all printable characters, but there is
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * no trailing nul byte. We'll assume that it's a string.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee char *s = malloc(nbytes + 1);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!s) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_out_of_memory(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to allocate string value");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (void) strncpy(s, c, nbytes);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s[nbytes] = '\0';
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_NewStringNative(jenv, s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee free(s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* return byte array */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = (*jenv)->NewByteArray(jenv, nbytes);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->SetByteArrayRegion(jenv, (jbyteArray)jobj, 0, nbytes,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (const jbyte *)c);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return NULL if memory could not be allocated (OutOfMemoryError is thrown in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * that case).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_recdata(dtj_java_consumer_t *jc, uint32_t size, caddr_t addr)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jobj;
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobject jrec;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (size) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case 1:
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobj = (*jenv)->NewObject(jenv, g_int_jc,
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_intinit_jm, (int)(*((uint8_t *)addr)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case 2:
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobj = (*jenv)->NewObject(jenv, g_int_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_intinit_jm, (int)(*((uint16_t *)addr)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case 4:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = (*jenv)->NewObject(jenv, g_int_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_intinit_jm, *((int32_t *)addr));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case 8:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = (*jenv)->NewObject(jenv, g_long_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_longinit_jm, *((int64_t *)addr));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_bytedata(jenv, size, addr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee if (!jobj) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (NULL); /* OutOfMemoryError pending */
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee jrec = (*jenv)->NewObject(jenv, g_scalar_jc,
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_scalarinit_jm, jobj, size);
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->DeleteLocalRef(jenv, jobj);
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (jrec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This is the record handling function passed to dtrace_work(). It differs
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * from the bufhandler registered with dtrace_handle_buffered() as follows:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 1. It does not have access to libdtrace formatted output.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 2. It is called once for every D program statement, not for every
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * output-producing D action or aggregation record. A statement may be a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * variable assignment, having no size and producing no output.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 3. It is called for the D exit() action; the bufhandler is not.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 4. In response to the printa() action, it is called with a record having an
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * action of type DTRACEACT_PRINTA. The bufhandler never sees that action
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * value. It only sees the output-producing aggregation records.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 5. It is called with a NULL record at the end of each probedata.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc = arg;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_eprobedesc_t *edesc = data->dtpda_edesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int r;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Update the record index to that of the current record, or to that of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the last record if rec is NULL (signalling end of probe data).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rec == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee r = edesc->dtepd_nrecs; /* end of probe data */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This record handler is called once for the printf() action,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * but there may be multiple records in the probedata
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * corresponding to the unformatted elements of that printf().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * We don't know ahead of time how many probedata records
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * libdtrace will consume to produce output for one printf()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * action, so we look back at the previous call to dtj_chewrec()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to see how many probedata records were consumed. All
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * non-null elements in the range from the previous record index
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * up to and not including the current record index are assumed
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to be unformatted printf() elements, and will be attached to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the PrintfRecord from the previous call. A null element in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * that range is the result of a D program statement preceding
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the printf() that is not a D action. These generate
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * probedata records accounted for by the null placeholder, but
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * do not advance the probedata offset and are not part of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * subsequent printf().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If rec->dtrd_size == 0, the record represents a D program
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * statement that is not a D action. It has no size and does
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * not advance the offset in the probedata. Handle it normally
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * without special-casing or premature return, since in all
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * cases we look at the previous record later in this function.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (r = jc->dtjj_consumer->dtjc_probedata_rec_i;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ((r < edesc->dtepd_nrecs) &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (edesc->dtepd_rec[r].dtrd_offset < rec->dtrd_offset));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee ++r) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Attach the Java representations of the libdtrace data elements
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * pertaining to the previous call to this record handler to the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * previous Java Record. (All data elements belonging to the current
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * probedata are added to a single list by the probedata consumer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * function dtj_chew() before this record consumer function is ever
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * called.) For example, if the previous Record was generated by the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * printf() action, and dtj_chew() listed 3 records for its 3
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * unformatted elements, those 3 libdtrace records comprise 1
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * PrintfRecord. Note that we cannot know how many data elements apply
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to the current rec until we find out the data index where the next
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * rec starts. (The knowledge of how many probedata records to consume
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * is private to libdtrace.)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_probedata_act == DTRACEACT_PRINTF) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataattach_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i, r - 1);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rec == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * End of probe data. Notify listeners of the new ProbeData
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * instance.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_probedata) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* previous probedata */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataclear_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdatanext_jm, jc->dtjj_probedata);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_probedata);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_probedata = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Do not wrap exception thrown from
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * ConsumerListener.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_printa_buffer);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_printa_buffer = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_NEXT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Set previous record action and data index to current */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_act = act;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i = r;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_DIFEXPR:
1ea5f93d6265bec480d4d5f9640ddffbfcd03df1Bryan Cantrill case DTRACEACT_TRACEMEM:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rec->dtrd_size == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The current record is not a D action, but a program
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * statement such as a variable assignment, not to be
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * confused with the trace() action.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Add a Record for the trace() action that references the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * native probedata element listed at the current index.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_trace_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_PRINTF:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Just add an empty PrintfRecord for now. We'll attach the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * unformatted elements in a subsequent call to this function.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * (We don't know how many there will be.)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_printf_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* defer formatted string to dtj_bufhandler() */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_PRINTA: {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jbuf = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggwalk_init(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_printa_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (rec->dtrd_format != 0));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_printa_buffer == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * Create a StringBuilder to collect the pieces of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * formatted output into a single String.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jbuf = (*jenv)->NewObject(jenv, g_buf_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_bufinit_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jbuf) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* OutOfMemoryError pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_printa_buffer = jbuf;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* defer aggregation records to dtj_bufhandler() */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_EXIT:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Add a Record for the exit() action that references the native
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * probedata element listed at the current index.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_exit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_NEXT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_THIS);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This is the probe handling function passed to dtrace_work(). It is is called
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * once every time a probe fires. It is the first of all the callbacks for the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * current probe. It is followed by multiple callbacks to dtj_chewrec(), one
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * for each probedata record. Each call to dtj_chewrec() is followed by zero or
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * more callbacks to the bufhandler, one for each output-producing action or
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * aggregation record.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_chew(const dtrace_probedata_t *data, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc = arg;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_eprobedesc_t *edesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_probedesc_t *pdesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_recdesc_t *rec;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int epid;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int cpu;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int nrecs;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int i;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jpdata = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jprobe = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jflow = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jflowkind = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jobj = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee edesc = data->dtpda_edesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee epid = (int)edesc->dtepd_epid;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pdesc = data->dtpda_pdesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee cpu = (int)data->dtpda_cpu;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((jprobe = dtj_new_probedesc(jc, pdesc)) == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee nrecs = edesc->dtepd_nrecs;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_flow) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *kind;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (data->dtpda_flow) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEFLOW_ENTRY:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee kind = "ENTRY";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEFLOW_RETURN:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee kind = "RETURN";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEFLOW_NONE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee kind = "NONE";
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee kind = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (kind != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int depth;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jflowkind = (*jenv)->NewStringUTF(jenv, kind);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jprobe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use the knowledge that libdtrace indents 2 spaces per
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * level in the call stack to calculate the depth.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee depth = (data->dtpda_indent / 2);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jflow = (*jenv)->NewObject(jenv, g_flow_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_flowinit_jm, jflowkind, depth);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jflowkind);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jprobe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Create ProbeData instance */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jpdata = (*jenv)->NewObject(jenv, g_pdata_jc, g_pdatainit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee epid, cpu, jprobe, jflow, nrecs);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jprobe);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jflow);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Populate the ProbeData list of Java data elements in advance so we
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * don't need to peek back in the record handler at libdtrace records
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * that have already been consumed. In the Java API, each ProbeData
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Record is generated by one D action, while in the native libdtrace
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * there may be more than one probedata record (each a single data
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * element) per D action. For example PrintfRecord has multiple
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * unformatted elements, each represented by a native probedata record,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * but combined by the API into a single PrintfRecord.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (i = 0; i < nrecs; ++i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rec = &edesc->dtepd_rec[i];
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * A statement that is not a D action, such as assignment to a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * variable, has no size. Add a NULL placeholder to the scratch
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * list of Java probedata elements in that case.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = NULL; /* initialize object reference to null */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rec->dtrd_size > 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_is_stack_action(rec->dtrd_action)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_new_probedata_stack_record(data,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rec, jc);
127bbe13a6d36580af6a8ded154f1201a6250772tomee } else if (dtj_is_symbol_action(rec->dtrd_action)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobj = dtj_new_probedata_symbol_record(data,
127bbe13a6d36580af6a8ded154f1201a6250772tomee rec, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_recdata(jc, rec->dtrd_size,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (data->dtpda_data + rec->dtrd_offset));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jpdata);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jpdata, g_pdataadd_jm, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jpdata);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_probedata != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_state(jenv, "unfinished probedata");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jpdata);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_probedata = jpdata;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Initialize per-consumer probedata fields */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_act = DTRACEACT_NONE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggwalk_init(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_CONSUME_THIS);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This is the buffered output handler registered with dtrace_handle_buffered().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * It's purpose is to make the output of the libdtrace print routines available
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to this API, without writing any of it to a file (such as stdout). This is
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * needed for the stack(), ustack(), and jstack() actions to get human-readable
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * stack values, since there is no public function in libdtrace to convert stack
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * values to strings. It is also used to get the formatted output of the D
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * printf() and printa() actions.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The bufhandler is called once for each output-producing, non-aggregating D
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * action, such as trace() or printf(), and once for each libdtrace aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * record (whether in response to the D printa() action, or the Consumer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * getAggregate() method). In the simple printa() case that takes one
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * aggregation and does not specify a format string, there is one libdtrace
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * record per tuple element plus one for the corresponding value. The complete
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * tuple/value pair becomes a single AggregationRecord exported by the API.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * When multiple aggregations are passed to printa(), each tuple is associated
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * with a list of values, one from each aggregation. If a printa() format
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * string does not specify placeholders for every aggregation value and tuple
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * member, callbacks for those values and tuple members are omitted (and the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * data is omitted from the resulting PrintaRecord).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Notes to characterize some non-obvious bufhandler behavior:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 1. dtj_bufhandler() is never called with bufdata->dtbda_recdesc->dtrd_action
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACEACT_PRINTA. That action only appears in the probedata consumer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * functions dtj_chew() and dtj_chewrec() before the bufhandler is called with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * subsequent aggregation records.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 2. If printa() specifies a format string argument, then the bufhandler is
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * called only for those elements of the tuple/value pair that are included in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the format string. If a stack() tuple member is omitted from the format
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * string, its human-readable representation will not be available to this API,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * so the stack frame array is also omitted from the resulting
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * AggregationRecord. The bufhandler is also called once for each string of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * characters surrounding printa() format string placeholders. For example,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * " %@d %d stack%k\n" results in the following callbacks:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - two spaces
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - the aggregation value
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - a single space
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - the first tuple member (an integer)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - " stack"
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - the second tuple member (a stack)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * - a newline
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * A NULL record (NULL dtbda_recdesc) distinguishes a callback with interstitial
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * format string characters from a callback with a tuple member or aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * value (which has a non-NULL recdesc). The contents are also distinguished by
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the following flags:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_BUFDATA_AGGKEY
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_BUFDATA_AGGVAL
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_BUFDATA_AGGFORMAT
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_BUFDATA_AGGLAST
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * There is no final callback with the complete formatted string, so that must
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * be concatenated across multiple callbacks to the bufhandler.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * 3. bufdata->dtbda_probe->dtpda_data may be overwritten by libdtrace print
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * routines. The address is cached in the dtj_chew() function in case it is
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * needed in the bufhandler.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* ARGSUSED */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_bufhandler(const dtrace_bufdata_t *bufdata, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *rec;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act = DTRACEACT_NONE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *s;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jstr = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Get the thread-specific java consumer. The bufhandler needs access
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * to the correct JNI state specific to either the consumer loop or the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * getAggregate() call (aggregation snapshots can be requested
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * asynchronously while the consumer loop generates PrintaRecords in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_work() for ConsumerListeners).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc = pthread_getspecific(g_dtj_consumer_key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * In at least one corner case (printa with multiple aggregations and a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * format string that does not completely specify the tuple), returning
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_HANDLE_ABORT does not prevent a subsequent callback to this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bufhandler. This check ensures that the invalid call is ignored.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (bufdata->dtbda_aggdata) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (dtj_agghandler(bufdata, jc));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s = bufdata->dtbda_buffered;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (s == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rec = bufdata->dtbda_recdesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rec) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_DIFEXPR:
1ea5f93d6265bec480d4d5f9640ddffbfcd03df1Bryan Cantrill case DTRACEACT_TRACEMEM:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* trace() action */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_PRINTF:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Only the formatted string was not available to dtj_chewrec(),
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * so we attach that now.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstr = dtj_NewStringNative(jenv, s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataset_formatted_jm, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_STACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_USTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_JSTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* stand-alone stack(), ustack(), or jstack() action */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstr = (*jenv)->NewStringUTF(jenv, s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jstr) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* OutOfMemoryError pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_stack_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_probedata_rec_i, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_USYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UADDR:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UMOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_SYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_MOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* stand-alone symbol lookup action */
127bbe13a6d36580af6a8ded154f1201a6250772tomee jstr = (*jenv)->NewStringUTF(jenv, s);
127bbe13a6d36580af6a8ded154f1201a6250772tomee if (!jstr) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* OutOfMemoryError pending */
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (DTRACE_HANDLE_ABORT);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_pdataadd_symbol_jm,
127bbe13a6d36580af6a8ded154f1201a6250772tomee jc->dtjj_consumer->dtjc_probedata_rec_i, jstr);
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->DeleteLocalRef(jenv, jstr);
127bbe13a6d36580af6a8ded154f1201a6250772tomee if ((*jenv)->ExceptionCheck(jenv)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee WRAP_EXCEPTION(jenv);
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (DTRACE_HANDLE_ABORT);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The record handler dtj_chewrec() defers nothing else to this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * bufhandler.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic boolean_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_is_stack_action(dtrace_actkind_t act)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee boolean_t stack_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_STACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_USTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_JSTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee stack_action = B_TRUE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee stack_action = B_FALSE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (stack_action);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic boolean_t
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_is_symbol_action(dtrace_actkind_t act)
127bbe13a6d36580af6a8ded154f1201a6250772tomee{
127bbe13a6d36580af6a8ded154f1201a6250772tomee boolean_t symbol_action;
127bbe13a6d36580af6a8ded154f1201a6250772tomee switch (act) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_USYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UADDR:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UMOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_SYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_MOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee symbol_action = B_TRUE;
127bbe13a6d36580af6a8ded154f1201a6250772tomee break;
127bbe13a6d36580af6a8ded154f1201a6250772tomee default:
127bbe13a6d36580af6a8ded154f1201a6250772tomee symbol_action = B_FALSE;
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (symbol_action);
127bbe13a6d36580af6a8ded154f1201a6250772tomee}
127bbe13a6d36580af6a8ded154f1201a6250772tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Called by get_aggregate() to clear only those aggregations specified by the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * caller.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_clear(const dtrace_aggdata_t *data, void *arg)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc = arg;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jboolean cleared = JNI_FALSE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jname = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_aggregate_spec) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_aggdesc_t *aggdesc = data->dtada_desc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jname = (*jenv)->NewStringUTF(jenv, aggdesc->dtagd_name);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jname) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_AGGWALK_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee cleared = (*jenv)->CallBooleanMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_aggregate_spec, g_aggspec_cleared_jm, jname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_AGGWALK_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (cleared ? DTRACE_AGGWALK_CLEAR : DTRACE_AGGWALK_NEXT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_average(caddr_t addr, uint64_t normal)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
e77b06d21580f630e0a7c437495ab283d3672828tomee int64_t *data = (int64_t *)addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (data[0] ?
e77b06d21580f630e0a7c437495ab283d3672828tomee (data[1] / (int64_t)normal / data[0]) : 0);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_avg_total(caddr_t addr, uint64_t normal)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
e77b06d21580f630e0a7c437495ab283d3672828tomee int64_t *data = (int64_t *)addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
e77b06d21580f630e0a7c437495ab283d3672828tomee return (data[1] / (int64_t)normal);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int64_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_avg_count(caddr_t addr)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
e77b06d21580f630e0a7c437495ab283d3672828tomee /* LINTED - alignment */
e77b06d21580f630e0a7c437495ab283d3672828tomee int64_t *data = (int64_t *)addr;
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee return (data[0]);
e77b06d21580f630e0a7c437495ab283d3672828tomee}
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomeestatic jobject
e77b06d21580f630e0a7c437495ab283d3672828tomeedtj_stddev_total_squares(JNIEnv *jenv, caddr_t addr, uint64_t normal)
e77b06d21580f630e0a7c437495ab283d3672828tomee{
e77b06d21580f630e0a7c437495ab283d3672828tomee jobject val128;
e77b06d21580f630e0a7c437495ab283d3672828tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uint64_t *data = (uint64_t *)addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
e77b06d21580f630e0a7c437495ab283d3672828tomee if (data[0] == 0) {
e77b06d21580f630e0a7c437495ab283d3672828tomee val128 = (*jenv)->CallStaticObjectMethod(jenv, g_bigint_jc,
e77b06d21580f630e0a7c437495ab283d3672828tomee g_bigint_val_jsm, (uint64_t)0);
e77b06d21580f630e0a7c437495ab283d3672828tomee } else {
e77b06d21580f630e0a7c437495ab283d3672828tomee val128 = dtj_int128(jenv, data[3], data[2]);
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee if (normal != 1) {
e77b06d21580f630e0a7c437495ab283d3672828tomee jobject divisor;
e77b06d21580f630e0a7c437495ab283d3672828tomee jobject tmp;
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee divisor = (*jenv)->CallStaticObjectMethod(jenv,
e77b06d21580f630e0a7c437495ab283d3672828tomee g_bigint_jc, g_bigint_val_jsm, normal);
e77b06d21580f630e0a7c437495ab283d3672828tomee tmp = val128;
e77b06d21580f630e0a7c437495ab283d3672828tomee val128 = (*jenv)->CallObjectMethod(jenv, tmp,
e77b06d21580f630e0a7c437495ab283d3672828tomee g_bigint_div_jm, divisor);
e77b06d21580f630e0a7c437495ab283d3672828tomee (*jenv)->DeleteLocalRef(jenv, tmp);
e77b06d21580f630e0a7c437495ab283d3672828tomee (*jenv)->DeleteLocalRef(jenv, divisor);
e77b06d21580f630e0a7c437495ab283d3672828tomee }
e77b06d21580f630e0a7c437495ab283d3672828tomee }
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee return (val128);
e77b06d21580f630e0a7c437495ab283d3672828tomee}
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee/*
e77b06d21580f630e0a7c437495ab283d3672828tomee * Return NULL if a java exception is pending, otherwise return a new
e77b06d21580f630e0a7c437495ab283d3672828tomee * StddevValue instance.
e77b06d21580f630e0a7c437495ab283d3672828tomee */
e77b06d21580f630e0a7c437495ab283d3672828tomeestatic jobject
e77b06d21580f630e0a7c437495ab283d3672828tomeedtj_stddev(JNIEnv *jenv, caddr_t addr, uint64_t normal)
e77b06d21580f630e0a7c437495ab283d3672828tomee{
e77b06d21580f630e0a7c437495ab283d3672828tomee jobject total_squares;
e77b06d21580f630e0a7c437495ab283d3672828tomee jobject stddev;
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee total_squares = dtj_stddev_total_squares(jenv, addr, normal);
e77b06d21580f630e0a7c437495ab283d3672828tomee stddev = (*jenv)->NewObject(jenv, g_aggstddev_jc, g_aggstddevinit_jm,
e77b06d21580f630e0a7c437495ab283d3672828tomee dtj_avg_count(addr), dtj_avg_total(addr, normal), total_squares);
e77b06d21580f630e0a7c437495ab283d3672828tomee (*jenv)->DeleteLocalRef(jenv, total_squares);
e77b06d21580f630e0a7c437495ab283d3672828tomee
e77b06d21580f630e0a7c437495ab283d3672828tomee return (stddev);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_new_probedata_stack_record(const dtrace_probedata_t *data,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *rec, dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee caddr_t addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Get raw stack data */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addr = data->dtpda_data + rec->dtrd_offset;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (dtj_new_stack_record(addr, rec, jc));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_new_tuple_stack_record(const dtrace_aggdata_t *data,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *rec, const char *s, dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee caddr_t addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobjectArray frames = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jobj = NULL; /* tuple element */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jstr = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Get raw stack data */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addr = data->dtada_data + rec->dtrd_offset;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_new_stack_record(addr, rec, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jobj) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL); /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstr = dtj_NewStringNative(jenv, s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frames = (*jenv)->CallStaticObjectMethod(jenv, g_stack_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_parsestack_jsm, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_attach_frames(jc, jobj, frames);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, frames);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee WRAP_EXCEPTION(jenv);
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (NULL);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (jobj);
127bbe13a6d36580af6a8ded154f1201a6250772tomee}
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_new_probedata_symbol_record(const dtrace_probedata_t *data,
127bbe13a6d36580af6a8ded154f1201a6250772tomee const dtrace_recdesc_t *rec, dtj_java_consumer_t *jc)
127bbe13a6d36580af6a8ded154f1201a6250772tomee{
127bbe13a6d36580af6a8ded154f1201a6250772tomee caddr_t addr;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee addr = data->dtpda_data + rec->dtrd_offset;
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (dtj_new_symbol_record(addr, rec, jc));
127bbe13a6d36580af6a8ded154f1201a6250772tomee}
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_new_tuple_symbol_record(const dtrace_aggdata_t *data,
127bbe13a6d36580af6a8ded154f1201a6250772tomee const dtrace_recdesc_t *rec, const char *s, dtj_java_consumer_t *jc)
127bbe13a6d36580af6a8ded154f1201a6250772tomee{
127bbe13a6d36580af6a8ded154f1201a6250772tomee caddr_t addr;
127bbe13a6d36580af6a8ded154f1201a6250772tomee JNIEnv *jenv = jc->dtjj_jenv;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobject jobj = NULL; /* tuple element */
127bbe13a6d36580af6a8ded154f1201a6250772tomee jstring jstr = NULL; /* lookup value */
127bbe13a6d36580af6a8ded154f1201a6250772tomee jstring tstr = NULL; /* trimmed lookup value */
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee addr = data->dtada_data + rec->dtrd_offset;
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobj = dtj_new_symbol_record(addr, rec, jc);
127bbe13a6d36580af6a8ded154f1201a6250772tomee if (!jobj) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (NULL); /* java exception pending */
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* Get symbol lookup */
127bbe13a6d36580af6a8ded154f1201a6250772tomee jstr = (*jenv)->NewStringUTF(jenv, s);
127bbe13a6d36580af6a8ded154f1201a6250772tomee if (!jstr) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* OutOfMemoryError pending */
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->DeleteLocalRef(jenv, jobj);
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (NULL);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* Trim leading and trailing whitespace */
127bbe13a6d36580af6a8ded154f1201a6250772tomee tstr = (*jenv)->CallObjectMethod(jenv, jstr, g_trim_jm);
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* trim() returns a new string; don't leak the old one */
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->DeleteLocalRef(jenv, jstr);
127bbe13a6d36580af6a8ded154f1201a6250772tomee jstr = tstr;
127bbe13a6d36580af6a8ded154f1201a6250772tomee tstr = NULL;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee dtj_attach_name(jc, jobj, jstr);
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->DeleteLocalRef(jenv, jstr);
127bbe13a6d36580af6a8ded154f1201a6250772tomee if ((*jenv)->ExceptionCheck(jenv)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/* Caller must be holding per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_aggwalk_init(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_aggid = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_expected = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_tuple != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* assert without crashing */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_state(jc->dtjj_jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "stale aggregation tuple");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_new_stack_record(const caddr_t addr, const dtrace_recdesc_t *rec,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uint64_t *pc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pid_t pid = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int size; /* size of raw bytes not including trailing zeros */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int i; /* index of last non-zero byte */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jbyteArray raw = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject stack = NULL; /* return value */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* trim trailing zeros */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (i = rec->dtrd_size - 1; (i >= 0) && !addr[i]; --i) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee size = (i + 1);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee raw = (*jenv)->NewByteArray(jenv, size);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!raw) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL); /* OutOfMemoryError pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->SetByteArrayRegion(jenv, raw, 0, size,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (const jbyte *)addr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, raw);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Create StackValueRecord instance from raw stack data */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_STACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee stack = (*jenv)->NewObject(jenv, g_stack_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_stackinit_jm, raw);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_USTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_JSTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Get pid of user process */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pc = (uint64_t *)(uintptr_t)addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pid = (pid_t)*pc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee stack = (*jenv)->NewObject(jenv, g_ustack_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_ustackinit_jm, pid, raw);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_argument(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "Expected stack action, got %d\n", act);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, raw);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (stack);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic jobject
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_new_symbol_record(const caddr_t addr, const dtrace_recdesc_t *rec,
127bbe13a6d36580af6a8ded154f1201a6250772tomee dtj_java_consumer_t *jc)
127bbe13a6d36580af6a8ded154f1201a6250772tomee{
127bbe13a6d36580af6a8ded154f1201a6250772tomee JNIEnv *jenv = jc->dtjj_jenv;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee dtrace_actkind_t act;
127bbe13a6d36580af6a8ded154f1201a6250772tomee uint64_t *pc;
127bbe13a6d36580af6a8ded154f1201a6250772tomee pid_t pid = -1;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobject symbol = NULL; /* return value */
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee act = rec->dtrd_action;
127bbe13a6d36580af6a8ded154f1201a6250772tomee switch (act) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_SYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_MOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* LINTED - alignment */
127bbe13a6d36580af6a8ded154f1201a6250772tomee pc = (uint64_t *)addr;
127bbe13a6d36580af6a8ded154f1201a6250772tomee symbol = (*jenv)->NewObject(jenv, g_symbol_jc,
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_symbolinit_jm, *pc);
127bbe13a6d36580af6a8ded154f1201a6250772tomee break;
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_USYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UADDR:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UMOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee /* Get pid of user process */
127bbe13a6d36580af6a8ded154f1201a6250772tomee pc = (uint64_t *)(uintptr_t)addr;
127bbe13a6d36580af6a8ded154f1201a6250772tomee pid = (pid_t)*pc;
127bbe13a6d36580af6a8ded154f1201a6250772tomee ++pc;
127bbe13a6d36580af6a8ded154f1201a6250772tomee symbol = (*jenv)->NewObject(jenv, g_usymbol_jc,
127bbe13a6d36580af6a8ded154f1201a6250772tomee g_usymbolinit_jm, pid, *pc);
127bbe13a6d36580af6a8ded154f1201a6250772tomee break;
127bbe13a6d36580af6a8ded154f1201a6250772tomee default:
127bbe13a6d36580af6a8ded154f1201a6250772tomee dtj_throw_illegal_argument(jenv,
127bbe13a6d36580af6a8ded154f1201a6250772tomee "Expected stack action, got %d\n", act);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee if ((*jenv)->ExceptionCheck(jenv)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee WRAP_EXCEPTION(jenv);
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (NULL);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee return (symbol);
127bbe13a6d36580af6a8ded154f1201a6250772tomee}
127bbe13a6d36580af6a8ded154f1201a6250772tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return NULL if java exception pending, otherwise return Distribution value.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_new_distribution(const dtrace_aggdata_t *data, const dtrace_recdesc_t *rec,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jlongArray jbuckets = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jdist = NULL; /* return value */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t *aggbuckets = (int64_t *)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (data->dtada_data + rec->dtrd_offset);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee size_t size = rec->dtrd_size;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t value;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uint64_t normal = data->dtada_normal;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t base, step;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int levels;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int n; /* number of buckets */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* distribution */
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe switch (act) {
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_LQUANTIZE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* first "bucket" used for range and step */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee value = *aggbuckets++;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee base = DTRACE_LQUANTIZE_BASE(value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee step = DTRACE_LQUANTIZE_STEP(value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee levels = DTRACE_LQUANTIZE_LEVELS(value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee size -= sizeof (int64_t); /* exclude non-bucket */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Add one for the base bucket and one for the bucket of values
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * less than the base.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee n = levels + 2;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_LLQUANTIZE:
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe value = *aggbuckets++;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe size -= sizeof (int64_t);
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe levels = size / sizeof (int64_t);
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe n = levels;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_QUANTIZE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee n = DTRACE_QUANTIZE_NBUCKETS;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee levels = n - 1; /* levels excludes base */
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (size != (n * sizeof (uint64_t)) || n < 1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_state(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "size mismatch: record %d, buckets %d", size,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (n * sizeof (uint64_t)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jbuckets = (*jenv)->NewLongArray(jenv, n);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jbuckets) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL); /* exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (n > 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->SetLongArrayRegion(jenv, jbuckets, 0, n, aggbuckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* check for ArrayIndexOutOfBounds */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jbuckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe switch (act) {
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_LQUANTIZE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Must pass 64-bit base and step or constructor gets junk. */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jdist = (*jenv)->NewObject(jenv, g_ldist_jc, g_ldistinit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee base, step, jbuckets);
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_QUANTIZE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jdist = (*jenv)->NewObject(jenv, g_dist_jc, g_distinit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jbuckets);
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe case DTRACEAGG_LLQUANTIZE:
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe jdist = (*jenv)->NewObject(jenv, g_lldist_jc, g_lldistinit_jm,
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe value, jbuckets);
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jbuckets);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jdist) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL); /* exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (normal != 1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jdist, g_dist_normal_jm, normal);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jdist);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (jdist);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_attach_frames(dtj_java_consumer_t *jc, jobject stack,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobjectArray frames)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->IsInstanceOf(jenv, stack, g_stack_jc)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, stack, g_stackset_frames_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frames);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else if ((*jenv)->IsInstanceOf(jenv, stack, g_ustack_jc)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, stack, g_ustackset_frames_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee frames);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
127bbe13a6d36580af6a8ded154f1201a6250772tomeestatic void
127bbe13a6d36580af6a8ded154f1201a6250772tomeedtj_attach_name(dtj_java_consumer_t *jc, jobject symbol, jstring s)
127bbe13a6d36580af6a8ded154f1201a6250772tomee{
127bbe13a6d36580af6a8ded154f1201a6250772tomee JNIEnv *jenv = jc->dtjj_jenv;
127bbe13a6d36580af6a8ded154f1201a6250772tomee
127bbe13a6d36580af6a8ded154f1201a6250772tomee if ((*jenv)->IsInstanceOf(jenv, symbol, g_symbol_jc)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->CallVoidMethod(jenv, symbol, g_symbolset_name_jm, s);
127bbe13a6d36580af6a8ded154f1201a6250772tomee } else if ((*jenv)->IsInstanceOf(jenv, symbol, g_usymbol_jc)) {
127bbe13a6d36580af6a8ded154f1201a6250772tomee (*jenv)->CallVoidMethod(jenv, symbol, g_usymbolset_name_jm, s);
127bbe13a6d36580af6a8ded154f1201a6250772tomee }
127bbe13a6d36580af6a8ded154f1201a6250772tomee}
127bbe13a6d36580af6a8ded154f1201a6250772tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Note: It is not valid to look outside the current libdtrace record in the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * given aggdata (except to get the aggregation ID from the first record).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return DTRACE_HANDLE_ABORT if java exception pending, otherwise
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTRACE_HANDLE_OK.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_agghandler(const dtrace_bufdata_t *bufdata, dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_aggdata_t *aggdata = bufdata->dtbda_aggdata;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_aggdesc_t *aggdesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *rec = bufdata->dtbda_recdesc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *s = bufdata->dtbda_buffered;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act = DTRACEACT_NONE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t aggid;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jobj = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (aggdata == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Assert without crashing */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_state(jenv, "null aggdata");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggdesc = aggdata->dtada_desc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Get the aggregation ID from the first record.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggid = *((int64_t *)(aggdata->dtada_data +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggdesc->dtagd_rec[0].dtrd_offset));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (aggid < 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Assert without crashing */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_argument(jenv, "negative aggregation ID");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_printa_snaptime) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Append buffered output if this is a printa() callback. */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jstr = dtj_NewStringNative(jenv, s);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * StringBuilder append() returns a reference to the
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * StringBuilder; must not leak the returned reference.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = (*jenv)->CallObjectMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_printa_buffer, g_buf_append_str_jm, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Test whether to include the aggregation if this is a
e77b06d21580f630e0a7c437495ab283d3672828tomee * getAggregate() call. Optimization: perform the inclusion
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * test only when the aggregation has changed.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (aggid != jc->dtjj_consumer->dtjc_aggid) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_included =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_is_included(aggdata, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jc->dtjj_consumer->dtjc_included) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_aggid = aggid;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Determine the expected number of tuple members. While it is not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * technically valid to look outside the current record in the current
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * aggdata, this implementation does so without a known failure case.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Any method relying only on the current callback record makes riskier
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * assumptions and still does not cover every corner case (for example,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * counting the records from index 1 up to and not including the index
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * of the current DTRACE_BUFDATA_AGGVAL record, which fails when a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * format string specifies the value ahead of one or more tuple
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * elements). Knowing that the calculation of the expected tuple size
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * is technically invalid (because it looks outside the current record),
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * we make the calculation at the earliest opportunity, before anything
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * might happen to invalidate any part of the aggdata. It ought to be
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * safe in any case: dtrd_action and dtrd_size do not appear ever to be
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * overwritten, and dtrd_offset is not used outside the current record.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * It is possible (if the assumptions here ever prove untrue) that the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * libdtrace buffered output handler may need to be enhanced to provide
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the expected number of tuple members.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_expected < 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int r;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (r = 1; r < aggdesc->dtagd_nrecs; ++r) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = aggdesc->dtagd_rec[r].dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (DTRACEACT_ISAGG(act) ||
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggdesc->dtagd_rec[r].dtrd_size == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_expected = r - 1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGKEY) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* record value is a tuple member */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_tuple == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_tuple = (*jenv)->NewObject(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_tuple_jc, g_tupleinit_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jc->dtjj_tuple) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_STACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_USTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEACT_JSTACK:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_new_tuple_stack_record(aggdata, rec, s, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_USYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UADDR:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_UMOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_SYM:
127bbe13a6d36580af6a8ded154f1201a6250772tomee case DTRACEACT_MOD:
127bbe13a6d36580af6a8ded154f1201a6250772tomee jobj = dtj_new_tuple_symbol_record(aggdata, rec, s, jc);
127bbe13a6d36580af6a8ded154f1201a6250772tomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobj = dtj_recdata(jc, rec->dtrd_size,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (aggdata->dtada_data + rec->dtrd_offset));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jobj) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_tuple,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_tupleadd_jm, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jobj);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGVAL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Record value is that of an aggregating action. The printa()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * format string may place the tuple ahead of the aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * value(s), so we can't be sure we have the tuple until we get
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the AGGLAST flag indicating the last callback associated with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the current tuple. Save the aggregation value or values
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * (multiple values if more than one aggregation is passed to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * printa()) until then.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggval_t *aggval;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jvalue = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = dtj_new_aggval(jc, aggdata, rec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jvalue) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggval = dtj_aggval_create(jenv, jvalue, aggdesc->dtagd_name,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggid);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!aggval) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* OutOfMemoryError pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jvalue);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!dtj_list_add(jc->dtjj_aggval_list, aggval)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* deletes jvalue reference */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggval_destroy(aggval, jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_out_of_memory(jenv, "Failed to add aggval");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGLAST) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* No more values associated with the current tuple. */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggval_t *aggval;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uu_list_walk_t *itr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int tuple_member_count;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jrec = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jname = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_expected == 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * singleton aggregation declared in D with no square
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * brackets
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_tuple = (*jenv)->GetStaticObjectField(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_tuple_jc, g_tuple_EMPTY_jsf);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_tuple == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_out_of_memory(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "Failed to reference Tuple.EMPTY");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_tuple == NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdatainvalidate_printa_jm);
8162146132b0fb9b7c6dc3371ff205edc236ebfatomee goto printa_output;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee tuple_member_count = (*jenv)->CallIntMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_tuple, g_tuplesize_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (tuple_member_count <
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_expected) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdatainvalidate_printa_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_tuple);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_tuple = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto printa_output;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee itr = uu_list_walk_start(jc->dtjj_aggval_list, 0);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee while ((aggval = uu_list_walk_next(itr)) != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * new AggregationRecord: Combine the aggregation value
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * with the saved tuple and add it to the current
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Aggregate or PrintaRecord.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jrec = (*jenv)->NewObject(jenv, g_aggrec_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggrecinit_jm, jc->dtjj_tuple,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggval->dtja_value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, aggval->dtja_value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggval->dtja_value = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jrec) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* aggregation name */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jname = (*jenv)->NewStringUTF(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggval->dtja_aggname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jname) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* OutOfMemoryError pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jrec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If the printa() format string specifies the value of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the aggregating action multiple times, PrintaRecord
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * ignores the attempt to add the duplicate record.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_printa_snaptime) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* add to PrintaRecord */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_aggrec_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jname, aggval->dtja_aggid, jrec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* add to Aggregate */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_aggregate, g_aggaddrec_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jname, aggval->dtja_aggid, jrec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jrec);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uu_list_walk_end(itr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_list_clear(jc->dtjj_aggval_list, dtj_aggval_destroy,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeprinta_output:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_printa_snaptime) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Get the formatted string associated with the current
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * tuple if this is a printa() callback.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring jstr = (*jenv)->CallObjectMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_printa_buffer, g_tostring_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * Clear the StringBuilder: this does not throw
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * exceptions. Reuse the StringBuilder until the end of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the current probedata then dispose of it.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_printa_buffer,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_bufsetlen_jm, 0);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Add formatted string to PrintaRecord */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_probedata,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_pdataadd_printa_str_jm, jc->dtjj_tuple, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jstr);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_ABORT);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_tuple);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_tuple = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_expected = -1;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTRACE_HANDLE_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return B_TRUE if the aggregation is included, B_FALSE otherwise. Only in the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * latter case might there be an exception pending.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic boolean_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_is_included(const dtrace_aggdata_t *data, dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_aggregate_spec) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jboolean included;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jstring aggname = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_aggdesc_t *aggdesc = data->dtada_desc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggname = (*jenv)->NewStringUTF(jenv, aggdesc->dtagd_name);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!aggname) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (B_FALSE);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee included = (*jenv)->CallBooleanMethod(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_aggregate_spec, g_aggspec_included_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, aggname);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (B_FALSE);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (included);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (B_TRUE);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return NULL if a java exception is pending, otherwise return a new
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * AggregationValue instance.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic jobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_new_aggval(dtj_java_consumer_t *jc, const dtrace_aggdata_t *data,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const dtrace_recdesc_t *rec)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject jvalue = NULL; /* return value */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_actkind_t act;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uint64_t normal;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee caddr_t addr;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int64_t value;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee act = rec->dtrd_action;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee normal = data->dtada_normal;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addr = data->dtada_data + rec->dtrd_offset;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (act == DTRACEAGG_AVG) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee value = dtj_average(addr, normal);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* LINTED - alignment */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee value = (*((int64_t *)addr)) / normal;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe if ((act == DTRACEAGG_QUANTIZE) || (act == DTRACEAGG_LQUANTIZE) ||
ae94d716ff8759d2dc2de680b5b85a291219a4c1Richard Lowe (act == DTRACEAGG_LLQUANTIZE)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = dtj_new_distribution(data, rec, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (act) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEAGG_COUNT:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = (*jenv)->NewObject(jenv, g_aggcount_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggcountinit_jm, value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEAGG_SUM:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = (*jenv)->NewObject(jenv, g_aggsum_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggsuminit_jm, value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEAGG_AVG:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = (*jenv)->NewObject(jenv, g_aggavg_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggavginit_jm, value, dtj_avg_total(addr,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee normal), dtj_avg_count(addr));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEAGG_MIN:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = (*jenv)->NewObject(jenv, g_aggmin_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggmininit_jm, value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACEAGG_MAX:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = (*jenv)->NewObject(jenv, g_aggmax_jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_aggmaxinit_jm, value);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
e77b06d21580f630e0a7c437495ab283d3672828tomee case DTRACEAGG_STDDEV:
e77b06d21580f630e0a7c437495ab283d3672828tomee jvalue = dtj_stddev(jenv, addr, normal);
e77b06d21580f630e0a7c437495ab283d3672828tomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jvalue = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_illegal_argument(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "unexpected aggregation action: %d", act);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (jvalue);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Stops the given consumer if it is running. Throws DTraceException if
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_stop() fails and no other exception is already pending. Clears and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * rethrows any pending exception in order to grab the global lock safely.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeevoid
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_stop(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int rc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jthrowable e;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (jc->dtjj_consumer->dtjc_state) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTJ_CONSUMER_GO:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTJ_CONSUMER_START:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee e = (*jenv)->ExceptionOccurred(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->ExceptionClear(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorEnter(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto rethrow;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rc = dtrace_status(jc->dtjj_consumer->dtjc_dtp);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rc != DTRACE_STATUS_STOPPED) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rc = dtrace_stop(jc->dtjj_consumer->dtjc_dtp);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto rethrow;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rc == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorEnter(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee goto rethrow;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "couldn't stop tracing: %s",
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(jc->dtjj_consumer->dtjc_dtp,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errno(jc->dtjj_consumer->dtjc_dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* safe to call with pending exception */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, g_caller_jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_state = DTJ_CONSUMER_STOP;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeerethrow:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Favor earlier pending exception over
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * exception thrown in this function.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->ExceptionClear(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->Throw(jenv, e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, e);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return Aggregate instance, or null if java exception pending.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeejobject
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_get_aggregate(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hrtime_t snaptime;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int rc;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jobject aggregate = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* Must not call MonitorEnter with a pending exception */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee if ((*jenv)->ExceptionCheck(jenv)) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee WRAP_EXCEPTION(jenv);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee return (NULL);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee }
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Aggregations must be snapped, walked, and cleared atomically,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * otherwise clearing loses data accumulated since the most recent snap.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * This per-consumer lock prevents dtrace_work() from snapping or
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * clearing aggregations while we're in the middle of this atomic
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * operation, so we continue to hold it until done clearing.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorEnter(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggwalk_init(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Snap aggregations
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * We need to record the snaptime here for the caller. Leaving it to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the caller to record the snaptime before calling getAggregate() may
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * be inaccurate because of the indeterminate delay waiting on the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * consumer lock before calling dtrace_aggregate_snap().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee snaptime = gethrtime();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_aggregate_snap(jc->dtjj_consumer->dtjc_dtp) != 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_error_t e;
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /*
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * The dataDropped() ConsumerListener method can throw an
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * exception in the getAggregate() thread if the drop handler is
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * invoked during dtrace_aggregate_snap().
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee if ((*jenv)->ExceptionCheck(jenv)) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* Do not wrap exception thrown from ConsumerListener */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* release per-consumer lock */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee return (NULL);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee }
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_get_dtrace_error(jc, &e) == DTJ_OK) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc, e.dtje_message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee if ((*jenv)->ExceptionCheck(jenv)) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /*
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * Wrap the exception thrown from ConsumerListener in this case,
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * so we can see that it unexpectedly reached this spot in
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * native code (dtrace_aggregate_snap should have returned
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee * non-zero).
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee WRAP_EXCEPTION(jenv);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* release per-consumer lock */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee return (NULL);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee }
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Create the Java representation of the aggregate snapshot. */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggregate = (*jenv)->NewObject(jenv, g_agg_jc, g_agginit_jm,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee snaptime);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_aggregate = aggregate;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
e77b06d21580f630e0a7c437495ab283d3672828tomee * Walk the aggregate, converting the data into Java Objects. Traverse
e77b06d21580f630e0a7c437495ab283d3672828tomee * in the order determined by libdtrace, respecting the various
e77b06d21580f630e0a7c437495ab283d3672828tomee * "aggsort" options, just as dtrace_work does when generating
e77b06d21580f630e0a7c437495ab283d3672828tomee * aggregations for the printa() action. libdtrace ordering is preserved
e77b06d21580f630e0a7c437495ab283d3672828tomee * in the "ordinal" property of AggregationRecord, since it would
e77b06d21580f630e0a7c437495ab283d3672828tomee * otherwise be lost when the records are hashed into the Aggregation's
e77b06d21580f630e0a7c437495ab283d3672828tomee * map. Neither the consumer loop nor the competing getAggregate()
e77b06d21580f630e0a7c437495ab283d3672828tomee * thread should depend on any particular record ordering (such as
e77b06d21580f630e0a7c437495ab283d3672828tomee * ordering by tuple key) to process records correctly.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * It is impractical to hold the global lock around
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_aggregate_print(), since it may take a long time (e.g. an
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * entire second) if it performs expensive conversions such as that
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * needed for user stack traces. Most libdtrace functions are not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * guaranteed to be MT-safe, even when each thread has its own dtrace
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * handle; or even if they are safe, there is no guarantee that future
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * changes may not make them unsafe. Fortunately in this case, however,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * only a per-consumer lock is necessary to avoid conflict with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_work() running in another thread (the consumer loop).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
e77b06d21580f630e0a7c437495ab283d3672828tomee rc = dtrace_aggregate_print(jc->dtjj_consumer->dtjc_dtp, NULL, NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rc != 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_error_t e;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_get_dtrace_error(jc, &e) != DTJ_OK) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (e.dtje_number != EINTR) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc, e.dtje_message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_aggwalk_init(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_aggregate_clear() clears all aggregations, and we need to
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * clear aggregations selectively. It also fails to preserve the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * lquantize() range and step size; using aggregate_walk() to clear
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * aggregations does not have this problem.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee rc = dtrace_aggregate_walk(jc->dtjj_consumer->dtjc_dtp, dtj_clear, jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (rc != 0) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_error_t e;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_get_dtrace_error(jc, &e) == DTJ_OK) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc, e.dtje_message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee aggregate = jc->dtjj_aggregate;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_aggregate = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (aggregate);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Process any requests, such as the setting of runtime options, enqueued during
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_sleep(). A Java exception is pending if this function returns
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTJ_ERR.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeestatic dtj_status_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_process_requests(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_request_t *r;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uu_list_t *list = jc->dtjj_consumer->dtjc_request_list;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee pthread_mutex_t *list_lock = &jc->dtjj_consumer->
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtjc_request_list_lock;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *opt;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee const char *val;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (void) pthread_mutex_lock(list_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee while (!dtj_list_empty(list)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee r = uu_list_first(list);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee uu_list_remove(list, r);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (r->dtjr_type) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTJ_REQUEST_OPTION:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee opt = dtj_string_list_first(r->dtjr_args);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee val = dtj_string_list_last(r->dtjr_args);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtrace_setopt(jc->dtjj_consumer->dtjc_dtp, opt,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee val) == -1) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "failed to set %s: %s", opt,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errmsg(jc->dtjj_consumer->dtjc_dtp,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_errno(jc->dtjj_consumer->dtjc_dtp)));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_request_destroy(r, NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (void) pthread_mutex_unlock(list_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_request_destroy(r, NULL);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (void) pthread_mutex_unlock(list_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Return DTJ_OK if the consumer loop is stopped normally by either the exit()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * action or the Consumer stop() method. Otherwise return DTJ_ERR if the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * consumer loop terminates abnormally with an exception pending.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_status_t
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeedtj_consume(dtj_java_consumer_t *jc)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee{
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee JNIEnv *jenv = jc->dtjj_jenv;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_hdl_t *dtp = jc->dtjj_consumer->dtjc_dtp;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee boolean_t done = B_FALSE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_error_t e;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee do {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!jc->dtjj_consumer->dtjc_interrupt) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtrace_sleep(dtp);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_interrupt) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee done = B_TRUE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_stop(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Exception left pending by Consumer
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * getAggregate() method.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else if (jc->dtjj_consumer->dtjc_process_list != NULL) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int nprocs = uu_list_numnodes(jc->dtjj_consumer->
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtjc_process_list);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_consumer->dtjc_procs_ended == nprocs) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee done = B_TRUE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_stop(jc);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Functions like dtrace_setopt() are not safe to call during
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * dtrace_sleep(). Check the request list every time we wake up
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * from dtrace_sleep().
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (!done) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_process_requests(jc) != DTJ_OK) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee /* Must not call MonitorEnter with a pending exception */
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee if ((*jenv)->ExceptionCheck(jenv)) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee WRAP_EXCEPTION(jenv);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee return (DTJ_ERR);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee }
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use the per-consumer lock to avoid conflict with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * get_aggregate() called from another thread.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorEnter(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee WRAP_EXCEPTION(jenv);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_interval_began_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
52aacb450723e8271d37836e1b5861c2072a3981tomee /* Don't wrap exception thrown from ConsumerListener */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = gethrtime();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee switch (dtrace_work(dtp, NULL, dtj_chew, dtj_chewrec, jc)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACE_WORKSTATUS_DONE:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee done = B_TRUE;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee case DTRACE_WORKSTATUS_OKAY:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee break;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee default:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Check for a pending exception that got us to this
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * error workstatus case.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Ensure valid initial state before releasing
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the consumer lock
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (dtj_get_dtrace_error(jc, &e) != DTJ_OK) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* java exception pending */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (e.dtje_number != EINTR) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Do not wrap DTraceException */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee dtj_throw_dtrace_exception(jc, e.dtje_message);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Check for ConsumerException before doing anything else with
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the JNIEnv.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Do not wrap exception thrown from ConsumerListener.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /* Release per-consumer lock */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_consumer->dtjc_printa_snaptime = 0;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Notify ConsumerListeners the the dtrace_work() interval ended
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * before releasing the lock.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->CallVoidMethod(jenv, jc->dtjj_caller,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee g_interval_ended_jm);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->MonitorExit(jenv, jc->dtjj_consumer_lock);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((*jenv)->ExceptionCheck(jenv)) {
52aacb450723e8271d37836e1b5861c2072a3981tomee /* Don't wrap exception thrown from ConsumerListener */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Check for a temporarily cleared exception set by a handler
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * that could not safely leave the exception pending because it
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * could not return an abort signal. Rethrow it now that it's
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * safe to do so (when it's possible to ensure that no JNI calls
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * will be made that are unsafe while an exception is pending).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (jc->dtjj_exception) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->Throw(jenv, jc->dtjj_exception);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (*jenv)->DeleteLocalRef(jenv, jc->dtjj_exception);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee jc->dtjj_exception = NULL;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_ERR);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } while (!done);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (DTJ_OK);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}