-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.cc
More file actions
85 lines (63 loc) · 2.26 KB
/
main.cc
File metadata and controls
85 lines (63 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "main.h"
#include "Callbacks.h"
#include <iostream>
#include <cassert>
#include <cstring>
using namespace std;
bool isReady = false;
MethodTable methodTable;
ClassTable classTable, fieldTable;
jvmtiEnv *jvmti = nullptr;
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
#ifdef DEBUG
cerr << "Agent loaded" << endl;
#endif
jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_2);
setCapabilities(jvmti);
setNotificationMode(jvmti);
setCallbacks(jvmti);
return JNI_OK;
}
void setNotificationMode(jvmtiEnv *jvmti)
{
jvmtiError error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL);
assert(!error);
error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
assert(!error);
error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL);
assert(!error);
error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL);
assert(!error);
error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
assert(!error);
error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
assert(!error);
}
void setCapabilities(jvmtiEnv *jvmti)
{
jvmtiCapabilities capabilities;
(void) memset(&capabilities, 0, sizeof(capabilities));
capabilities.can_generate_method_entry_events = 1;
capabilities.can_generate_method_exit_events = 1;
capabilities.can_generate_all_class_hook_events = 1;
jvmtiError error = jvmti->AddCapabilities(&capabilities);
assert(!error);
}
void setCallbacks(jvmtiEnv *jvmti)
{
#ifdef DEBUG
cerr << "Setting callbacks" << endl;
#endif
jvmtiEventCallbacks callbacks;
(void) memset(&callbacks, 0, sizeof(callbacks));
callbacks.VMStart = &onVMStart;
callbacks.MethodEntry = &onMethodEntry;
// callbacks.MethodExit = &onMethodExit;
callbacks.VMInit = &onVMInit;
// we don't start rewriting bytecode until we've hit main
callbacks.ClassFileLoadHook = &onClassFileLoad;
callbacks.VMDeath = &flushBuffers;
jvmtiError error = jvmti->SetEventCallbacks(&callbacks, (jint) sizeof(callbacks));
assert(!error);
}