Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/GetThreadListStackTraces/libOneGetThreadListStackTraces.cpp
41155 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2020, NTT DATA.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
#include <jni.h>
26
#include <jvmti.h>
27
#include <inttypes.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
31
#define MAX_FRAMES 100
32
#define ERR_MSG_LEN 1024
33
34
#ifdef __cplusplus
35
extern "C" {
36
#endif
37
38
static jvmtiEnv *jvmti = NULL;
39
40
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
41
return jvm->GetEnv(reinterpret_cast<void**>(&jvmti), JVMTI_VERSION_11);
42
}
43
44
static void check_frame_info(JNIEnv *env, jvmtiFrameInfo *fi1, jvmtiFrameInfo *fi2) {
45
char err_msg[ERR_MSG_LEN] = {0};
46
if (fi1->method != fi2->method) { /* jvmtiFrameInfo::method */
47
snprintf(err_msg, sizeof(err_msg),
48
"method is different: fi1 = %" PRIxPTR ", fi2 = %" PRIxPTR,
49
(uintptr_t)fi1->method, (uintptr_t)fi2->method);
50
env->FatalError(err_msg);
51
} else if (fi1->location != fi2->location) { /* jvmtiFrameInfo::location */
52
snprintf(err_msg, sizeof(err_msg),
53
"location is different: fi1 = %" PRId64 ", fi2 = %" PRId64,
54
(int64_t)fi1->location, (int64_t)fi2->location);
55
env->FatalError(err_msg);
56
}
57
}
58
59
static void check_stack_info(JNIEnv *env, jvmtiStackInfo *si1, jvmtiStackInfo *si2) {
60
char err_msg[ERR_MSG_LEN] = {0};
61
62
jboolean is_same = env->IsSameObject(si1->thread, si2->thread);
63
if (env->ExceptionOccurred()) {
64
env->ExceptionDescribe();
65
env->FatalError(__FILE__);
66
}
67
68
if (!is_same) { /* jvmtiStackInfo::thread */
69
snprintf(err_msg, sizeof(err_msg),
70
"thread is different: si1 = %" PRIxPTR ", si2 = %" PRIxPTR,
71
(uintptr_t)si1->thread, (uintptr_t)si2->thread);
72
env->FatalError(err_msg);
73
} else if (si1->state != si2->state) { /* jvmtiStackInfo::state */
74
snprintf(err_msg, sizeof(err_msg),
75
"state is different: si1 = %d, si2 = %d", si1->state, si2->state);
76
env->FatalError(err_msg);
77
} else if (si1->frame_count != si2->frame_count) { /* jvmtiStackInfo::frame_count */
78
snprintf(err_msg, sizeof(err_msg),
79
"frame_count is different: si1 = %d, si2 = %d",
80
si1->frame_count, si2->frame_count);
81
env->FatalError(err_msg);
82
} else {
83
/* Iterate all jvmtiFrameInfo to check */
84
for (int i = 0; i < si1->frame_count; i++) {
85
check_frame_info(env, &si1->frame_buffer[i], &si2->frame_buffer[i]);
86
}
87
}
88
}
89
90
JNIEXPORT void JNICALL Java_OneGetThreadListStackTraces_checkCallStacks(JNIEnv *env, jclass cls, jthread thread) {
91
jvmtiStackInfo *stack_info, *target_info, *target_one_info;
92
jvmtiError result;
93
char err_msg[ERR_MSG_LEN] = {0};
94
95
/* Get all stack traces */
96
jint num_threads;
97
result = jvmti->GetAllStackTraces(MAX_FRAMES, &stack_info, &num_threads);
98
if (result != JVMTI_ERROR_NONE) {
99
snprintf(err_msg, sizeof(err_msg),
100
"GetAllStackTraces(): result = %d", result);
101
env->FatalError(err_msg);
102
}
103
104
/* Find jvmtiStackInfo for `thread` (in arguments) */
105
jboolean is_same;
106
target_info = NULL;
107
for (jint i = 0; i < num_threads; i++) {
108
is_same = env->IsSameObject(stack_info[i].thread, thread);
109
if (env->ExceptionOccurred()) {
110
env->ExceptionDescribe();
111
env->FatalError(__FILE__);
112
}
113
if (is_same) {
114
target_info = &stack_info[i];
115
break;
116
}
117
}
118
if (target_info == NULL) {
119
env->FatalError("Target thread not found");
120
}
121
122
/*
123
* Get jvmtiStackInfo via GetThreadListStackTraces().
124
* It expects to perform in Thread Local Handshake because thread count is 1.
125
*/
126
result = jvmti->GetThreadListStackTraces(1, &thread,
127
MAX_FRAMES, &target_one_info);
128
if (result != JVMTI_ERROR_NONE) {
129
snprintf(err_msg, sizeof(err_msg),
130
"GetThreadListStackTraces(): result = %d", result);
131
env->FatalError(err_msg);
132
}
133
134
check_stack_info(env, target_info, target_one_info);
135
136
jvmti->Deallocate(reinterpret_cast<unsigned char *>(stack_info));
137
jvmti->Deallocate(reinterpret_cast<unsigned char *>(target_one_info));
138
}
139
140
#ifdef __cplusplus
141
}
142
#endif
143
144