12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "jvmti.h"
28 #include "jni_tools.h"
29 #include "agent_common.h"
30 #include "JVMTITools.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 #ifndef JNI_ENV_ARG
37
38 #ifdef __cplusplus
39 #define JNI_ENV_ARG(x, y) y
40 #define JNI_ENV_PTR(x) x
41 #else
42 #define JNI_ENV_ARG(x,y) x, y
43 #define JNI_ENV_PTR(x) (*x)
44 #endif
45
46 #endif
47
48 #define PASSED 0
49 #define STATUS_FAILED 2
50
51 static jvmtiEnv *jvmti = NULL;
52 static jint result = PASSED;
53 static jboolean printdump = JNI_FALSE;
54 static jvmtiCapabilities jvmti_caps;
55 static jint dummy_user_data = 0;
56 static jboolean user_data_error_flag = JNI_FALSE;
57
58 #define HEAP_ROOT_REF_KIND_BASE 100
59 #define MISSED_REF_KIND_BASE 300
60
61 typedef enum {
62 rthread,
63 rclass,
64 rother,
65 rmark
66 } refKind;
258 return Agent_Initialize(jvm, options, reserved);
259 }
260
261 JNIEXPORT jint JNICALL Agent_OnAttach_heapref(JavaVM *jvm, char *options, void *reserved) {
262 return Agent_Initialize(jvm, options, reserved);
263 }
264
265 JNIEXPORT jint JNI_OnLoad_heapref(JavaVM *jvm, char *options, void *reserved) {
266 return JNI_VERSION_1_8;
267 }
268 #endif
269
270 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
271 jint res;
272 jvmtiError err;
273
274 if (options != NULL && strcmp(options, "printdump") == 0) {
275 printdump = JNI_TRUE;
276 }
277
278 res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
279 JVMTI_VERSION_1_1);
280 if (res != JNI_OK || jvmti == NULL) {
281 printf("Wrong result of a valid call to GetEnv!\n");
282 return JNI_ERR;
283 }
284
285 memset((void*)&jvmti_caps, 0, sizeof(jvmtiCapabilities));
286 jvmti_caps.can_tag_objects = 1;
287 err = jvmti->AddCapabilities(&jvmti_caps);
288 if (err != JVMTI_ERROR_NONE) {
289 printf("Error (AddCapabilities): %s (%d)\n", TranslateError(err), err);
290 return JNI_ERR;
291 }
292
293 return JNI_OK;
294 }
295
296 jvmtiIterationControl JNICALL
297 heapMarkCallback(jlong class_tag, jlong size, jlong* tag_ptr, void* user_data) {
298 const MyTag* const tag = newTag(rmark, (const MyTag*)(intptr_t)class_tag, size, NULL);
299 *tag_ptr = (intptr_t)tag;
470 heapRootCallback,
471 stackReferenceCallback,
472 objectReferenceCallback,
473 &dummy_user_data);
474 if (err != JVMTI_ERROR_NONE) {
475 printf("Error (IterateOverReachableObjects): %s (%d)\n", TranslateError(err), err);
476 result = STATUS_FAILED;
477 }
478
479 if (printdump == JNI_TRUE) {
480 printf("<html><head><title>Heap Dump</title></head><body><pre>\n");
481 walk(fakeRoot, 0, "roots");
482 printf("\n------------------- MISSED ------------------\n\n");
483 walk(missed, 0, "missed");
484 printf("</pre></body></html>\n");
485 }
486
487 return result;
488 }
489
490 #ifdef __cplusplus
491 }
492 #endif
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "jvmti.h"
28 #include "jni_tools.h"
29 #include "agent_common.h"
30 #include "JVMTITools.h"
31
32 extern "C" {
33
34
35 #define PASSED 0
36 #define STATUS_FAILED 2
37
38 static jvmtiEnv *jvmti = NULL;
39 static jint result = PASSED;
40 static jboolean printdump = JNI_FALSE;
41 static jvmtiCapabilities jvmti_caps;
42 static jint dummy_user_data = 0;
43 static jboolean user_data_error_flag = JNI_FALSE;
44
45 #define HEAP_ROOT_REF_KIND_BASE 100
46 #define MISSED_REF_KIND_BASE 300
47
48 typedef enum {
49 rthread,
50 rclass,
51 rother,
52 rmark
53 } refKind;
245 return Agent_Initialize(jvm, options, reserved);
246 }
247
248 JNIEXPORT jint JNICALL Agent_OnAttach_heapref(JavaVM *jvm, char *options, void *reserved) {
249 return Agent_Initialize(jvm, options, reserved);
250 }
251
252 JNIEXPORT jint JNI_OnLoad_heapref(JavaVM *jvm, char *options, void *reserved) {
253 return JNI_VERSION_1_8;
254 }
255 #endif
256
257 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
258 jint res;
259 jvmtiError err;
260
261 if (options != NULL && strcmp(options, "printdump") == 0) {
262 printdump = JNI_TRUE;
263 }
264
265 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
266 if (res != JNI_OK || jvmti == NULL) {
267 printf("Wrong result of a valid call to GetEnv!\n");
268 return JNI_ERR;
269 }
270
271 memset((void*)&jvmti_caps, 0, sizeof(jvmtiCapabilities));
272 jvmti_caps.can_tag_objects = 1;
273 err = jvmti->AddCapabilities(&jvmti_caps);
274 if (err != JVMTI_ERROR_NONE) {
275 printf("Error (AddCapabilities): %s (%d)\n", TranslateError(err), err);
276 return JNI_ERR;
277 }
278
279 return JNI_OK;
280 }
281
282 jvmtiIterationControl JNICALL
283 heapMarkCallback(jlong class_tag, jlong size, jlong* tag_ptr, void* user_data) {
284 const MyTag* const tag = newTag(rmark, (const MyTag*)(intptr_t)class_tag, size, NULL);
285 *tag_ptr = (intptr_t)tag;
456 heapRootCallback,
457 stackReferenceCallback,
458 objectReferenceCallback,
459 &dummy_user_data);
460 if (err != JVMTI_ERROR_NONE) {
461 printf("Error (IterateOverReachableObjects): %s (%d)\n", TranslateError(err), err);
462 result = STATUS_FAILED;
463 }
464
465 if (printdump == JNI_TRUE) {
466 printf("<html><head><title>Heap Dump</title></head><body><pre>\n");
467 walk(fakeRoot, 0, "roots");
468 printf("\n------------------- MISSED ------------------\n\n");
469 walk(missed, 0, "missed");
470 printf("</pre></body></html>\n");
471 }
472
473 return result;
474 }
475
476 }
|