/*
Copyright (c) 1998--2006 Benhur Stein
This file is part of Pajé.
Pajé is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
Pajé is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
for more details.
You should have received a copy of the GNU Lesser General Public License
along with Pajé; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
//////////////////////////////////////////////////
/* Author: Geovani Ricardo Wiedenhoft */
/* Email: grw@inf.ufsm.br */
//////////////////////////////////////////////////
#include"JRastro.h"
/*Identificador(contador) das threads, variavel declarada em JRastro.c*/
extern long threadId;
/*Identificador da thread main == Identificador da JVM, declarada em JRastro.c*/
extern long jrst_mainThread;
/*Somador aleatorio, obtido pelo tempo, declarada em JRastro.c*/
extern long adder;
//rst_buffer_t * get_buffer(jvmtiEnv *jvmtiLocate, jthread thread)
//{
// rst_buffer_t *ptr;
// jvmtiError error;
//
// error = (*jvmtiLocate)->GetThreadLocalStorage(jvmtiLocate, thread, (void**)&ptr);
// if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// char name[MAX_NAME_THREAD];
// jvmtiError err;
//
// jrst_get_thread_name(jvmtiLocate, thread, name, MAX_NAME_THREAD);
// if(name == NULL){
// (void)strcpy(name,"Unknown");
// }
// printf("getbuffer thread name=[%s]\n",name);
// return NULL;
// trace_initialize(jvmtiLocate, thread, name);
//
// err = (*jvmtiLocate)->GetThreadLocalStorage(jvmtiLocate, thread, (void**)&ptr);
// jrst_check_error(jvmtiLocate, err, "Cannot Get Thread Local Storage");
//
// }
// return ptr;
//
//}
void trace_initialize(jvmtiEnv *jvmtiLocate, jthread thread, char *name)
{
if(traces){
rst_buffer_t *ptr;
jvmtiThreadInfo infoThread;
jvmtiError error;
ptr = (rst_buffer_t *) malloc(sizeof(rst_buffer_t));
jrst_enter_critical_section(jvmtiLocate, gagent->monitor_thread);
error=(*jvmtiLocate)->GetThreadInfo(jvmtiLocate, thread, &infoThread);
jrst_check_error(jvmtiLocate, error, "Cannot get Thread Info");
rst_init_ptr(ptr, (u_int64_t)jrst_mainThread, (u_int64_t)(threadId + adder));
rst_event_isiii_ptr(ptr, INITIALIZE, (int)threadId, name, (int)infoThread.priority, (int)infoThread.is_daemon, (int)infoThread.thread_group);
threadId ++;
error = (*jvmtiLocate)->SetThreadLocalStorage(jvmtiLocate, thread, (void*)ptr);
jrst_check_error(jvmtiLocate, error, "Cannot Set Thread Local Storage");
jrst_exit_critical_section(jvmtiLocate, gagent->monitor_thread);
error=(*jvmtiLocate)->Deallocate(jvmtiLocate, (unsigned char *)infoThread.name);
jrst_check_error(jvmtiLocate, error,"Cannot deallocate memory");
}
}
void trace_finalize(jvmtiEnv *jvmtiLocate, jthread thread)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(jvmtiLocate, gagent->monitor_thread);
//ptr = get_buffer(jvmtiLocate, thread);
error = (*jvmtiLocate)->GetThreadLocalStorage(jvmtiLocate, thread, (void**)&ptr);
if (ptr == NULL){
jrst_exit_critical_section(jvmtiLocate, gagent->monitor_thread);
return;
}
rst_event_ptr(ptr, FINALIZE);
rst_finalize_ptr(ptr);
error = (*jvmtiLocate)->SetThreadLocalStorage(jvmtiLocate, thread, NULL);
jrst_check_error(jvmtiLocate, error, "Cannot Set Thread Local Storage");
jrst_exit_critical_section(jvmtiLocate, gagent->monitor_thread);
}
}
static int tag = 0;
void trace_event_object_alloc(jthread thread, jobject object, char *nameClass)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jlong size;
int id = 0;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL){
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
error = (*GET_JVMTI())->GetObjectSize(GET_JVMTI(), object, &size);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Thread Local Storage");
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_tag);
tag++;
id = tag;
// printf("alloc=[%x] thread=[%s] size=[%ld]\n", id, name, (long)size);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_tag);
rst_event_lis_ptr(ptr, JVMTI_EVENT_VM_OBJECT_ALLOC, size, id, nameClass);
error = (*GET_JVMTI())->SetTag(GET_JVMTI(), object, (jlong)id);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Tag");
/*if(tag == 500){
error = (*GET_JVMTI())->ForceGarbageCollection(GET_JVMTI());
jrst_check_error(GET_JVMTI(), error, "Cannot Force Garbage Collection");
}*/
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_object_alloc_new_array(jthread thread, jobject object, char *nameClass)
{
if(traces){
jvmtiError error;
jlong size;
int id = 0;
// jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_new_array);
if(ptr_new_array == NULL){
ptr_new_array = (rst_buffer_t *)malloc(sizeof(rst_buffer_t));
rst_init_ptr(ptr_new_array, (u_int64_t)jrst_mainThread, (u_int64_t)THREAD_NEW_ARRAY);
}
error = (*GET_JVMTI())->GetObjectSize(GET_JVMTI(), object, &size);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Thread Local Storage");
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_tag);
tag++;
id = tag;
// printf("new array=[%x]\n", id);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_tag);
rst_event_lis_ptr(ptr_new_array, JVMTI_EVENT_VM_OBJECT_ALLOC, size, id, nameClass);
error = (*GET_JVMTI())->SetTag(GET_JVMTI(), object, (jlong)id);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Tag");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_new_array);
// jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_object_free(jlong tag)
{
if(traces){
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_buffer);
if(ptr_monitor == NULL){
ptr_monitor = (rst_buffer_t *)malloc(sizeof(rst_buffer_t));
rst_init_ptr(ptr_monitor, (u_int64_t)jrst_mainThread, (u_int64_t)THREAD_MONITOR);
}
// printf("free=[%x]\n", (int)tag);
rst_event_i_ptr(ptr_monitor, JVMTI_EVENT_OBJECT_FREE, (int)tag);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_buffer);
}
}
void trace_event_gc_start()
{
if(traces){
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_buffer);
if(ptr_monitor == NULL){
ptr_monitor = (rst_buffer_t *)malloc(sizeof(rst_buffer_t));
rst_init_ptr(ptr_monitor, (u_int64_t)jrst_mainThread, (u_int64_t)THREAD_MONITOR);
}
rst_event_ptr(ptr_monitor, JVMTI_EVENT_GARBAGE_COLLECTION_START);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_buffer);
}
}
void trace_event_gc_finish()
{
if(traces){
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_buffer);
rst_event_ptr(ptr_monitor, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_buffer);
}
}
void trace_event_method_entry_obj_init(jthread thread, jobject object, int method, char *nameClass)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jlong id = 0;
jlong size = 0;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
//ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_entry_objc thread method=[%x]\n",method);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
error = (*GET_JVMTI())->GetObjectSize(GET_JVMTI(), object, &size);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Thread Local Storage");
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_tag);
tag++;
id = (jlong)tag;
//printf("enter =[%d]\n", (int)id);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_tag);
rst_event_liis_ptr(ptr, EVENT_METHOD_ENTRY_ALLOC, size, (int)id, method, nameClass);
error = (*GET_JVMTI())->SetTag(GET_JVMTI(), object, id);
jrst_check_error(GET_JVMTI(), error, "Cannot Set Tag");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_method_entry_obj(jthread thread, int object, int method)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
//ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_entry_objc thread method=[%x]\n",method);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_ii_ptr(ptr, JVMTI_EVENT_METHOD_ENTRY, object, method);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_method_entry(jthread thread, int method)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
//ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_entry thread method=[%d]\n",method);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, METHOD_ENTRY, method);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_method_exit(jthread thread)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
// ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_ptr(ptr, JVMTI_EVENT_METHOD_EXIT);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_exception(jthread thread, int exception)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
// ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, METHOD_EXCEPTION, exception);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_method_exit_exception(jthread thread)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
// ptr = get_buffer(GET_JVMTI(), thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL || error!= JVMTI_ERROR_NONE){
// printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_ptr(ptr, METHOD_EXIT_EXCEPTION);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_method_load(int method, char *name, unsigned access_flags, int klass)
{
if(traces){
rst_event_isii_ptr(ptr_loader, METHOD_LOAD, method, name, klass, access_flags);
}
}
void trace_event_class_load(int klass, char *name)
{
if(traces){
if(ptr_loader == NULL){
ptr_loader = (rst_buffer_t *)malloc(sizeof(rst_buffer_t));
rst_init_ptr(ptr_loader, (u_int64_t)jrst_mainThread, (u_int64_t)THREAD_LOADER);
}
rst_event_is_ptr(ptr_loader, CLASS_LOAD, klass, name);
}
}
void trace_event_monitor_contended_enter(jvmtiEnv *jvmtiLocate, jthread thread, int object)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL){
//printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, MONITOR_ENTER, object);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_monitor_contended_entered(jvmtiEnv *jvmtiLocate, jthread thread, int object)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL){
// printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, MONITOR_ENTERED, object);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_monitor_wait(jvmtiEnv *jvmtiLocate, jthread thread, int object)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL){
//printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, MONITOR_WAIT, object);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
void trace_event_monitor_waited(jvmtiEnv *jvmtiLocate, jthread thread, int object)
{
if(traces){
rst_buffer_t *ptr;
jvmtiError error;
jrst_enter_critical_section(GET_JVMTI(), gagent->monitor_thread);
error = (*GET_JVMTI())->GetThreadLocalStorage(GET_JVMTI(), thread, (void**)&ptr);
if (ptr == NULL){
// printf("trace_event_method_saida thread \n");
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
return;
}
rst_event_i_ptr(ptr, MONITOR_WAITED, object);
jrst_exit_critical_section(GET_JVMTI(), gagent->monitor_thread);
}
}
syntax highlighted by Code2HTML, v. 0.9.1