8282076: Merge some debug agent changes from the loom repo
Reviewed-by: amenkov, lmesnik
This commit is contained in:
parent
f86f38a8af
commit
253cf7852f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -534,6 +534,62 @@ synthesizeUnloadEvent(void *signatureVoid, void *envVoid)
|
||||
/* Garbage Collection Happened */
|
||||
static unsigned int garbageCollected = 0;
|
||||
|
||||
/*
|
||||
* Run the event through each HandlerNode's filter, and if it passes, call the HandlerNode's
|
||||
* HandlerFunction for the event, and then report all accumulated events to the debugger.
|
||||
*/
|
||||
static void
|
||||
filterAndHandleEvent(JNIEnv *env, EventInfo *evinfo, EventIndex ei,
|
||||
struct bag *eventBag, jbyte eventSessionID)
|
||||
{
|
||||
debugMonitorEnter(handlerLock);
|
||||
{
|
||||
HandlerNode *node;
|
||||
char *classname;
|
||||
|
||||
/* We must keep track of all classes prepared to know what's unloaded */
|
||||
if (evinfo->ei == EI_CLASS_PREPARE) {
|
||||
classTrack_addPreparedClass(env, evinfo->clazz);
|
||||
}
|
||||
|
||||
node = getHandlerChain(ei)->first;
|
||||
classname = getClassname(evinfo->clazz);
|
||||
|
||||
/* Filter the event over each handler node. */
|
||||
while (node != NULL) {
|
||||
/* Save next so handlers can remove themselves. */
|
||||
HandlerNode *next = NEXT(node);
|
||||
jboolean shouldDelete;
|
||||
|
||||
if (eventFilterRestricted_passesFilter(env, classname,
|
||||
evinfo, node,
|
||||
&shouldDelete)) {
|
||||
HandlerFunction func = HANDLER_FUNCTION(node);
|
||||
if (func == NULL) {
|
||||
EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL");
|
||||
}
|
||||
/* Handle the event by calling the event handler. */
|
||||
(*func)(env, evinfo, node, eventBag);
|
||||
}
|
||||
if (shouldDelete) {
|
||||
/* We can safely free the node now that we are done using it. */
|
||||
(void)freeHandler(node);
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
jvmtiDeallocate(classname);
|
||||
}
|
||||
debugMonitorExit(handlerLock);
|
||||
|
||||
/*
|
||||
* The events destined for the debugger were accumulated in eventBag. Report all these events.
|
||||
*/
|
||||
if (eventBag != NULL) {
|
||||
reportEvents(env, eventSessionID, evinfo->thread, evinfo->ei,
|
||||
evinfo->clazz, evinfo->method, evinfo->location, eventBag);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The JVMTI generic event callback. Each event is passed to a sequence of
|
||||
* handlers in a chain until the chain ends or one handler
|
||||
@ -634,51 +690,7 @@ event_callback(JNIEnv *env, EventInfo *evinfo)
|
||||
}
|
||||
}
|
||||
|
||||
debugMonitorEnter(handlerLock);
|
||||
{
|
||||
HandlerNode *node;
|
||||
char *classname;
|
||||
|
||||
/* We must keep track of all classes prepared to know what's unloaded */
|
||||
if (evinfo->ei == EI_CLASS_PREPARE) {
|
||||
classTrack_addPreparedClass(env, evinfo->clazz);
|
||||
}
|
||||
|
||||
node = getHandlerChain(evinfo->ei)->first;
|
||||
classname = getClassname(evinfo->clazz);
|
||||
|
||||
while (node != NULL) {
|
||||
/* save next so handlers can remove themselves */
|
||||
HandlerNode *next = NEXT(node);
|
||||
jboolean shouldDelete;
|
||||
|
||||
if (eventFilterRestricted_passesFilter(env, classname,
|
||||
evinfo, node,
|
||||
&shouldDelete)) {
|
||||
HandlerFunction func;
|
||||
|
||||
func = HANDLER_FUNCTION(node);
|
||||
if ( func == NULL ) {
|
||||
EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL");
|
||||
}
|
||||
(*func)(env, evinfo, node, eventBag);
|
||||
}
|
||||
if (shouldDelete) {
|
||||
/* We can safely free the node now that we are done
|
||||
* using it.
|
||||
*/
|
||||
(void)freeHandler(node);
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
jvmtiDeallocate(classname);
|
||||
}
|
||||
debugMonitorExit(handlerLock);
|
||||
|
||||
if (eventBag != NULL) {
|
||||
reportEvents(env, eventSessionID, thread, evinfo->ei,
|
||||
evinfo->clazz, evinfo->method, evinfo->location, eventBag);
|
||||
}
|
||||
filterAndHandleEvent(env, evinfo, ei, eventBag, eventSessionID);
|
||||
|
||||
/* we are continuing after VMDeathEvent - now we are dead */
|
||||
if (evinfo->ei == EI_VM_DEATH) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -463,14 +463,18 @@ handleMethodEnterEvent(JNIEnv *env, EventInfo *evinfo,
|
||||
*/
|
||||
JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO));
|
||||
|
||||
if ( (!eventFilter_predictFiltering(step->stepHandlerNode,
|
||||
clazz, classname))
|
||||
&& ( step->granularity != JDWP_STEP_SIZE(LINE)
|
||||
|| hasLineNumbers(method) ) ) {
|
||||
/*
|
||||
* We need to figure out if we are entering a method that we want to resume
|
||||
* single stepping in. If the class of this method is being filtered out, then
|
||||
* we don't resume. Otherwise, if we are not line stepping then we resume, and
|
||||
* if we are line stepping we don't resume unless the method has LineNumbers.
|
||||
*/
|
||||
jboolean filteredOut = eventFilter_predictFiltering(step->stepHandlerNode, clazz, classname);
|
||||
jboolean isStepLine = step->granularity == JDWP_STEP_SIZE(LINE);
|
||||
if (!filteredOut && (!isStepLine || hasLineNumbers(method))) {
|
||||
/*
|
||||
* We've found a suitable method in which to stop. Step
|
||||
* until we reach the next safe location to complete the step->,
|
||||
* and we can get rid of the method entry handler.
|
||||
* We've found a suitable method in which to resume stepping.
|
||||
* We can also get rid of the method entry handler now.
|
||||
*/
|
||||
enableStepping(thread);
|
||||
if ( step->methodEnterHandlerNode != NULL ) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -69,7 +69,7 @@ typedef struct ThreadNode {
|
||||
unsigned int pendingInterrupt : 1; /* true if thread is interrupted while handling an event. */
|
||||
unsigned int isDebugThread : 1; /* true if this is one of our debug agent threads. */
|
||||
unsigned int suspendOnStart : 1; /* true for new threads if we are currently in a VM.suspend(). */
|
||||
unsigned int isStarted : 1; /* THREAD_START or VIRTUAL_THREAD_SCHEDULED event received. */
|
||||
unsigned int isStarted : 1; /* THREAD_START event received. */
|
||||
unsigned int popFrameEvent : 1;
|
||||
unsigned int popFrameProceed : 1;
|
||||
unsigned int popFrameThread : 1;
|
||||
|
Loading…
Reference in New Issue
Block a user