8282076: Merge some debug agent changes from the loom repo

Reviewed-by: amenkov, lmesnik
This commit is contained in:
Chris Plummer 2022-02-23 21:09:41 +00:00
parent f86f38a8af
commit 253cf7852f
3 changed files with 72 additions and 56 deletions

View File

@ -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) {

View File

@ -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 ) {

View File

@ -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;