|
Java example source code file (agent_util.c)
The agent_util.c Java example source code/* * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This source code is provided to illustrate the usage of a given feature * or technique and has been deliberately simplified. Additional steps * required for a production-quality application, such as security checks, * input validation and proper error handling, might not be present in * this sample code. */ #include <agent_util.h> /* ------------------------------------------------------------------- */ /* Generic C utility functions */ /* Send message to stdout or whatever the data output location is */ void stdout_message(const char * format, ...) { va_list ap; va_start(ap, format); (void)vfprintf(stdout, format, ap); va_end(ap); } /* Send message to stderr or whatever the error output location is and exit */ void fatal_error(const char * format, ...) { va_list ap; va_start(ap, format); (void)vfprintf(stderr, format, ap); (void)fflush(stderr); va_end(ap); exit(3); } /* Get a token from a string (strtok is not MT-safe) * str String to scan * seps Separation characters * buf Place to put results * max Size of buf * Returns NULL if no token available or can't do the scan. */ char * get_token(char *str, char *seps, char *buf, int max) { int len; buf[0] = 0; if ( str==NULL || str[0]==0 ) { return NULL; } str += strspn(str, seps); if ( str[0]==0 ) { return NULL; } len = (int)strcspn(str, seps); if ( len >= max ) { return NULL; } (void)strncpy(buf, str, len); buf[len] = 0; return str+len; } /* Determines if a class/method is specified by a list item * item String that represents a pattern to match * If it starts with a '*', then any class is allowed * If it ends with a '*', then any method is allowed * cname Class name, e.g. "java.lang.Object" * mname Method name, e.g. "<init>" * Returns 1(true) or 0(false). */ static int covered_by_list_item(char *item, char *cname, char *mname) { int len; len = (int)strlen(item); if ( item[0]=='*' ) { if ( strncmp(mname, item+1, len-1)==0 ) { return 1; } } else if ( item[len-1]=='*' ) { if ( strncmp(cname, item, len-1)==0 ) { return 1; } } else { int cname_len; cname_len = (int)strlen(cname); if ( strncmp(cname, item, (len>cname_len?cname_len:len))==0 ) { if ( cname_len >= len ) { /* No method name supplied in item, we must have matched */ return 1; } else { int mname_len; mname_len = (int)strlen(mname); item += cname_len+1; len -= cname_len+1; if ( strncmp(mname, item, (len>mname_len?mname_len:len))==0 ) { return 1; } } } } return 0; } /* Determines if a class/method is specified by this list * list String of comma separated pattern items * cname Class name, e.g. "java.lang.Object" * mname Method name, e.g. "<init>" * Returns 1(true) or 0(false). */ static int covered_by_list(char *list, char *cname, char *mname) { char token[1024]; char *next; if ( list[0] == 0 ) { return 0; } next = get_token(list, ",", token, sizeof(token)); while ( next != NULL ) { if ( covered_by_list_item(token, cname, mname) ) { return 1; } next = get_token(next, ",", token, sizeof(token)); } return 0; } /* Determines which class and methods we are interested in * cname Class name, e.g. "java.lang.Object" * mname Method name, e.g. "<init>" * include_list Empty or an explicit list for inclusion * exclude_list Empty or an explicit list for exclusion * Returns 1(true) or 0(false). */ int interested(char *cname, char *mname, char *include_list, char *exclude_list) { if ( exclude_list!=NULL && exclude_list[0]!=0 && covered_by_list(exclude_list, cname, mname) ) { return 0; } if ( include_list!=NULL && include_list[0]!=0 && !covered_by_list(include_list, cname, mname) ) { return 0; } return 1; } /* ------------------------------------------------------------------- */ /* Generic JVMTI utility functions */ /* Every JVMTI interface returns an error code, which should be checked * to avoid any cascading errors down the line. * The interface GetErrorName() returns the actual enumeration constant * name, making the error messages much easier to understand. */ void check_jvmti_error(jvmtiEnv *jvmti, jvmtiError errnum, const char *str) { if ( errnum != JVMTI_ERROR_NONE ) { char *errnum_str; errnum_str = NULL; (void)(*jvmti)->GetErrorName(jvmti, errnum, &errnum_str); fatal_error("ERROR: JVMTI: %d(%s): %s\n", errnum, (errnum_str==NULL?"Unknown":errnum_str), (str==NULL?"":str)); } } /* All memory allocated by JVMTI must be freed by the JVMTI Deallocate * interface. */ void deallocate(jvmtiEnv *jvmti, void *ptr) { jvmtiError error; error = (*jvmti)->Deallocate(jvmti, ptr); check_jvmti_error(jvmti, error, "Cannot deallocate memory"); } /* Allocation of JVMTI managed memory */ void * allocate(jvmtiEnv *jvmti, jint len) { jvmtiError error; void *ptr; error = (*jvmti)->Allocate(jvmti, len, (unsigned char **)&ptr); check_jvmti_error(jvmti, error, "Cannot allocate memory"); return ptr; } /* Add demo jar file to boot class path (the BCI Tracker class must be * in the boot classpath) * * WARNING: This code assumes that the jar file can be found at one of: * ${JAVA_HOME}/demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar * ${JAVA_HOME}/../demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar * where JAVA_HOME may refer to the jre directory. * Both these values are added to the boot classpath. * These locations are only true for these demos, installed * in the JDK area. Platform specific code could be used to * find the location of the DLL or .so library, and construct a * path name to the jar file, relative to the library location. */ void add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name) { jvmtiError error; char *file_sep; int max_len; char *java_home; char jar_path[FILENAME_MAX+1]; java_home = NULL; error = (*jvmti)->GetSystemProperty(jvmti, "java.home", &java_home); check_jvmti_error(jvmti, error, "Cannot get java.home property value"); if ( java_home == NULL || java_home[0] == 0 ) { fatal_error("ERROR: Java home not found\n"); } #ifdef WIN32 file_sep = "\\"; #else file_sep = "/"; #endif max_len = (int)(strlen(java_home) + strlen(demo_name)*2 + strlen(file_sep)*5 + 16 /* ".." "demo" "jvmti" ".jar" NULL */ ); if ( max_len > (int)sizeof(jar_path) ) { fatal_error("ERROR: Path to jar file too long\n"); } (void)strcpy(jar_path, java_home); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, "demo"); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, "jvmti"); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, demo_name); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, demo_name); (void)strcat(jar_path, ".jar"); error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path); check_jvmti_error(jvmti, error, "Cannot add to boot classpath"); (void)strcpy(jar_path, java_home); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, ".."); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, "demo"); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, "jvmti"); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, demo_name); (void)strcat(jar_path, file_sep); (void)strcat(jar_path, demo_name); (void)strcat(jar_path, ".jar"); error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path); check_jvmti_error(jvmti, error, "Cannot add to boot classpath"); } /* ------------------------------------------------------------------- */ Other Java examples (source code examples)Here is a short list of links related to this Java agent_util.c source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.