From a0489793a5a4f22c388c3c418ac7eb6167f55191 Mon Sep 17 00:00:00 2001 From: Jason Feng Date: Tue, 10 Dec 2024 07:23:12 -0500 Subject: [PATCH] CRIU DebugOnRestore mode is disabled when debug events are hooked isDebugOnRestoreEnabled() returns false if some debug-specific flags/events are enabled/hooked, this matches J9::Options::isFSDNeeded() in compiler/control/J9Options.cpp; DebugOnRestore mode is enabled when CRIU is enabled, -XX:+DebugOnRestore is specified, JDWP is not enabled, and no debug-specific flags/events are enabled/hooked; When DebugOnRestore mode is enabled, debug related events and hooks can't be enabled or hooked pre-checkpoint, isDebugAgentDisabled() returns TRUE in this case, otherwise FALSE. Signed-off-by: Jason Feng --- runtime/jvmti/jvmtiCapability.c | 26 ++++++--- runtime/jvmti/jvmtiHook.c | 71 +++++++++--------------- runtime/jvmti/jvmtiStartup.c | 98 ++++++++++++++++++++++++++++++--- runtime/oti/j9nonbuilder.h | 2 + runtime/oti/vm_api.h | 38 +++++++++++-- runtime/vm/CRIUHelpers.cpp | 10 +++- runtime/vm/intfunc.c | 1 + 7 files changed, 178 insertions(+), 68 deletions(-) diff --git a/runtime/jvmti/jvmtiCapability.c b/runtime/jvmti/jvmtiCapability.c index 35f7ff48cf8..77a47b6d5b3 100644 --- a/runtime/jvmti/jvmtiCapability.c +++ b/runtime/jvmti/jvmtiCapability.c @@ -115,7 +115,8 @@ jvmtiGetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr J9JavaVM * vm = j9env->vm; J9JVMTIData * jvmtiData = J9JVMTI_DATA_FROM_VM(vm); jvmtiCapabilities rv_capabilities; - J9HookInterface ** vmHook = vm->internalVMFunctions->getVMHookInterface(vm); + J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions; + J9HookInterface **vmHook = vmFuncs->getVMHookInterface(vm); jvmtiError rc; Trc_JVMTI_jvmtiGetPotentialCapabilities_Entry(env); @@ -206,8 +207,13 @@ jvmtiGetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr } if ((*vmHook)->J9HookIsEnabled(vmHook, J9HOOK_VM_POP_FRAMES_INTERRUPT)) { - rv_capabilities.can_pop_frame = 1; - rv_capabilities.can_force_early_return = 1; +#if defined(J9VM_OPT_CRIU_SUPPORT) + if (!vmFuncs->isDebugAgentDisabled(vm)) +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ + { + rv_capabilities.can_pop_frame = 1; + rv_capabilities.can_force_early_return = 1; + } } if ((*vmHook)->J9HookIsEnabled(vmHook, J9HOOK_VM_REQUIRED_DEBUG_ATTRIBUTES) || @@ -231,7 +237,12 @@ jvmtiGetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr if ((*vmHook)->J9HookIsEnabled(vmHook, J9HOOK_VM_REQUIRED_DEBUG_ATTRIBUTES) || (vm->requiredDebugAttributes & J9VM_DEBUG_ATTRIBUTE_CAN_ACCESS_LOCALS) ) { - rv_capabilities.can_access_local_variables = 1; +#if defined(J9VM_OPT_CRIU_SUPPORT) + if (!vmFuncs->isDebugAgentDisabled(vm)) +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ + { + rv_capabilities.can_access_local_variables = 1; + } } rv_capabilities.can_tag_objects = 1; @@ -548,16 +559,13 @@ mapCapabilitiesToEvents(J9JVMTIEnv * j9env, jvmtiCapabilities * capabilities, J9 #if defined(J9VM_OPT_CRIU_SUPPORT) J9JavaVM *vm = j9env->vm; - J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions; - BOOLEAN skipHookReserve = vmFuncs->isCheckpointAllowed(vm) - && vmFuncs->isDebugOnRestoreEnabled(vm); - /* Skip J9HookReserve for the events required by JDWP agent pre-checkpoint when DebugOnRestore is enabled, + /* Skip J9HookReserve for the events required by JDWP agent pre-checkpoint when isDebugAgentDisabled() returns TRUE, * these events will be registered post-restore if a JDWP agent is specified in the restore option file, * otherwise they are going to be unregistered by J9HookUnregister() which only clears J9HOOK_FLAG_HOOKED, * but not J9HOOK_FLAG_RESERVED. * J9HookUnreserve() might clear the flag set by other callers. */ - if (!skipHookReserve) + if (!vm->internalVMFunctions->isDebugAgentDisabled(vm)) #endif /* defined(J9VM_OPT_CRIU_SUPPORT)*/ { if (capabilities->can_generate_single_step_events) { diff --git a/runtime/jvmti/jvmtiHook.c b/runtime/jvmti/jvmtiHook.c index 1ba4bcd2d6f..d83df3528ba 100644 --- a/runtime/jvmti/jvmtiHook.c +++ b/runtime/jvmti/jvmtiHook.c @@ -155,8 +155,6 @@ static BOOLEAN shouldPostEvent(J9VMThread *currentThread, J9Method *method); #if defined(J9VM_OPT_CRIU_SUPPORT) static void jvmtiHookVMCheckpoint(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); static void jvmtiHookVMRestore(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); -static void jvmtiHookVMRestoreCRIUInit(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); -static void jvmtiHookVMRestoreStartAgent(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); static void hookDisableHelper(J9JavaVM *vm, J9HookInterface **vmHook, UDATA eventNum, J9HookFunction function, BOOLEAN unreserve, void *userData); static void @@ -557,37 +555,6 @@ jvmtiHookVMCheckpoint(J9HookInterface **hook, UDATA eventNum, void *eventData, v TRACE_JVMTI_EVENT_RETURN(jvmtiHookVMCheckpoint); } -static void -jvmtiHookVMRestoreCRIUInit(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) -{ - Trc_JVMTI_jvmtiHookVMRestoreCRIUInit_Entry(); - criuRestoreInitializeLib(((J9RestoreEvent *)eventData)->currentThread->javaVM, (J9JVMTIEnv *)userData); - TRACE_JVMTI_EVENT_RETURN(jvmtiHookVMRestoreCRIUInit); -} - -static void -jvmtiHookVMRestoreStartAgent(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) -{ - J9VMThread *currentThread = ((J9RestoreEvent *)eventData)->currentThread; - J9JavaVM *vm = currentThread->javaVM; - J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions; - - Trc_JVMTI_jvmtiHookVMRestoreStartAgent_Entry(); - vmFuncs->internalExitVMToJNI(currentThread); - if (J9_ARE_ANY_BITS_SET(vm->checkpointState.flags, J9VM_CRIU_IS_JDWP_ENABLED)) { - criuRestoreStartAgent(vm); - } else { - /* Last part of cleanup if there was no JDWP agent specified. - * This releases VM access hence can't be invoked within criuDisableHooks() from - * J9HOOK_VM_PREPARING_FOR_RESTORE. - */ - jvmtiEnv *jvmti_env = vm->checkpointState.jvmtienv; - (*jvmti_env)->DisposeEnvironment(jvmti_env); - } - vmFuncs->internalEnterVMFromJNI(currentThread); - TRACE_JVMTI_EVENT_RETURN(jvmtiHookVMRestoreStartAgent); -} - static void jvmtiHookVMRestore(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) { @@ -1075,6 +1042,21 @@ jvmtiHookClassLoad(J9HookInterface** hook, UDATA eventNum, void* eventData, void UDATA isEventHookable(J9JVMTIEnv * j9env, jvmtiEvent event) { +#if defined(J9VM_OPT_CRIU_SUPPORT) + J9JavaVM *vm = j9env->vm; + if (vm->internalVMFunctions->isDebugAgentDisabled(vm)) { + switch(event) { + case JVMTI_EVENT_FRAME_POP: /* fall through */ + case JVMTI_EVENT_FIELD_ACCESS: /* fall through */ + case JVMTI_EVENT_FIELD_MODIFICATION: /* fall through */ + case JVMTI_EVENT_SINGLE_STEP: /* fall through */ + case JVMTI_EVENT_BREAKPOINT: + return FALSE; + default: + break; + } + } +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ return processEvent(j9env, event, hookIsDisabled) == 0; } @@ -1136,6 +1118,18 @@ hookNonEventCapabilities(J9JVMTIEnv * j9env, jvmtiCapabilities * capabilities) J9JVMTIHookInterfaceWithID * gcOmrHook = &j9env->gcOmrHook; J9JVMTIData * jvmtiData = J9JVMTI_DATA_FROM_VM(vm); +#if defined(J9VM_OPT_CRIU_SUPPORT) + if (vm->internalVMFunctions->isDebugAgentDisabled(vm)) { + if (capabilities->can_pop_frame + || capabilities->can_force_early_return + || capabilities->can_access_local_variables + || capabilities->can_generate_breakpoint_events + ) { + return 1; + } + } +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ + if (capabilities->can_generate_breakpoint_events) { if (hookRegister(vmHook, J9HOOK_VM_BREAKPOINT, jvmtiHookBreakpoint, OMR_GET_CALLSITE(), j9env)) { return 1; @@ -2046,17 +2040,6 @@ hookGlobalEvents(J9JVMTIData * jvmtiData) return 1; } -#if defined(J9VM_OPT_CRIU_SUPPORT) - if (vm->internalVMFunctions->isDebugOnRestoreEnabled(vm)) { - if ((*vmHook)->J9HookRegisterWithCallSite(vmHook, J9HOOK_TAG_AGENT_ID | J9HOOK_VM_PREPARING_FOR_RESTORE, jvmtiHookVMRestoreCRIUInit, OMR_GET_CALLSITE(), jvmtiData, J9HOOK_AGENTID_FIRST)) { - return 1; - } - if ((*vmHook)->J9HookRegisterWithCallSite(vmHook, J9HOOK_TAG_AGENT_ID | J9HOOK_VM_CRIU_RESTORE, jvmtiHookVMRestoreStartAgent, OMR_GET_CALLSITE(), jvmtiData, J9HOOK_AGENTID_FIRST)) { - return 1; - } - } -#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ - if ((*vmHook)->J9HookRegisterWithCallSite(vmHook, J9HOOK_TAG_AGENT_ID | J9HOOK_VM_SHUTTING_DOWN, jvmtiHookVMShutdownLast, OMR_GET_CALLSITE(), jvmtiData, J9HOOK_AGENTID_LAST)) { return 1; } diff --git a/runtime/jvmti/jvmtiStartup.c b/runtime/jvmti/jvmtiStartup.c index 81a30e6b43e..a4f0b99f4e5 100644 --- a/runtime/jvmti/jvmtiStartup.c +++ b/runtime/jvmti/jvmtiStartup.c @@ -65,6 +65,10 @@ I_32 JNICALL loadAgentLibraryOnAttach(struct J9JavaVM *vm, const char *library, static BOOLEAN isAgentLibraryLoaded(J9JavaVM *vm, const char *library, BOOLEAN decorate); static jint createAgentLibraryWithOption(J9JavaVM *vm, J9VMInitArgs *argsList, IDATA agentIndex, J9JVMTIAgentLibrary **agentLibrary, CreateAgentOption createAgentOption, BOOLEAN *isJDWPagent); static BOOLEAN processAgentLibraryFromArgsList(J9JavaVM *vm, J9VMInitArgs *argsList, BOOLEAN loadLibrary, CreateAgentOption createAgentOption); +#if defined(J9VM_OPT_CRIU_SUPPORT) +static void jvmtiHookVMRestoreCRIUInit(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); +static void jvmtiHookVMRestoreStartAgent(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData); +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ #define INSTRUMENT_LIBRARY "instrument" @@ -267,6 +271,53 @@ processAgentLibraryFromArgsList(J9JavaVM *vm, J9VMInitArgs *argsList, BOOLEAN lo } #if defined(J9VM_OPT_CRIU_SUPPORT) +/** + * A hook method to invoke criuRestoreInitializeLib(). + * + * @param[in] hook the VM hook interface, not used + * @param[in] eventNum the event number, not used + * @param[in] eventData the event data, not used + * @param[in] userData the registered user data + */ +static void +jvmtiHookVMRestoreCRIUInit(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) +{ + Trc_JVMTI_jvmtiHookVMRestoreCRIUInit_Entry(); + criuRestoreInitializeLib(((J9RestoreEvent *)eventData)->currentThread->javaVM, (J9JVMTIEnv *)userData); + Trc_JVMTI_jvmtiHookVMRestoreCRIUInit_Exit(); +} + +/** + * A hook method to start agents or cleanup post-restore. + * + * @param[in] hook the VM hook interface, not used + * @param[in] eventNum the event number, not used + * @param[in] eventData the event data + * @param[in] userData the registered user data, not used + */ +static void +jvmtiHookVMRestoreStartAgent(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) +{ + J9VMThread *currentThread = ((J9RestoreEvent *)eventData)->currentThread; + J9JavaVM *vm = currentThread->javaVM; + J9InternalVMFunctions const * const vmFuncs = vm->internalVMFunctions; + + Trc_JVMTI_jvmtiHookVMRestoreStartAgent_Entry(); + vmFuncs->internalExitVMToJNI(currentThread); + if (J9_ARE_ANY_BITS_SET(vm->checkpointState.flags, J9VM_CRIU_IS_JDWP_ENABLED)) { + criuRestoreStartAgent(vm); + } else { + /* Last part of cleanup if there was no JDWP agent specified. + * This releases VM access hence can't be invoked within criuDisableHooks() from + * J9HOOK_VM_PREPARING_FOR_RESTORE. + */ + jvmtiEnv *jvmti_env = vm->checkpointState.jvmtienv; + (*jvmti_env)->DisposeEnvironment(jvmti_env); + } + vmFuncs->internalEnterVMFromJNI(currentThread); + Trc_JVMTI_jvmtiHookVMRestoreStartAgent_Exit(); +} + /** * Add JVMTI capabilities before checkpoint. * This is required for debugger support when JIT is enabled. @@ -418,14 +469,45 @@ IDATA J9VMDllMain(J9JavaVM *vm, IDATA stage, void *reserved) hshelpUTRegister(vm); #if defined(J9VM_OPT_CRIU_SUPPORT) - /* - * Adding capabilities is required before checkpoint if JIT is enabled. - * Following code can be removed when JIT allows capabilities to be added after restore. - */ - if (vm->internalVMFunctions->isDebugOnRestoreEnabled(vm)) { - Trc_JVMTI_criuAddCapabilities_invoked(); - /* ignore the failure, it won't cause a problem if JDWP is not enabled later */ - criuAddCapabilities(vm, NULL != vm->jitConfig); + { + /* The isDebugEventOrFlagEnabled calculation matches a part of J9::Options::isFSDNeeded() + * in compiler/control/J9Options.cpp. + */ + BOOLEAN isDebugEventOrFlagEnabled = J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_BREAKPOINT) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_FRAME_POP) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_FRAME_POPPED) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_GET_FIELD) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_PUT_FIELD) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_GET_STATIC_FIELD) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_PUT_STATIC_FIELD) +#if defined (J9VM_INTERP_HOT_CODE_REPLACEMENT) + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_POP_FRAMES_INTERRUPT) +#endif +#if defined(J9VM_JIT_FULL_SPEED_DEBUG) + || (vm->requiredDebugAttributes & J9VM_DEBUG_ATTRIBUTE_CAN_ACCESS_LOCALS) +#endif + || J9_EVENT_IS_HOOKED_OR_RESERVED(vm->hookInterface, J9HOOK_VM_SINGLE_STEP); + J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions; + BOOLEAN isDebugOnRestoreEnabled = !isDebugEventOrFlagEnabled + && J9_ARE_ALL_BITS_SET(vm->checkpointState.flags, J9VM_CRIU_SUPPORT_DEBUG_ON_RESTORE) + && vmFuncs->isCRaCorCRIUSupportEnabled(vm); + + if (isDebugOnRestoreEnabled) { + J9HookInterface ** vmHook = vmFuncs->getVMHookInterface(vm); + if ((*vmHook)->J9HookRegisterWithCallSite(vmHook, J9HOOK_TAG_AGENT_ID | J9HOOK_VM_PREPARING_FOR_RESTORE, jvmtiHookVMRestoreCRIUInit, OMR_GET_CALLSITE(), jvmtiData, J9HOOK_AGENTID_FIRST)) { + goto _error; + } + if ((*vmHook)->J9HookRegisterWithCallSite(vmHook, J9HOOK_TAG_AGENT_ID | J9HOOK_VM_CRIU_RESTORE, jvmtiHookVMRestoreStartAgent, OMR_GET_CALLSITE(), jvmtiData, J9HOOK_AGENTID_FIRST)) { + goto _error; + } + /* Adding capabilities is required before checkpoint if JIT is enabled. + * Following code can be removed when JIT allows capabilities to be added after restore. + */ + Trc_JVMTI_criuAddCapabilities_invoked(); + /* ignore the failure, it won't cause a problem if JDWP is not enabled later */ + criuAddCapabilities(vm, NULL != vm->jitConfig); + vm->checkpointState.isDebugOnRestoreEnabled = isDebugOnRestoreEnabled; + } } #endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index a5e83f265aa..fcfda15b364 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -4456,6 +4456,7 @@ typedef struct J9CRIUCheckpointState { UDATA javaDebugThreadCount; jvmtiEnv *jvmtienv; jvmtiCapabilities requiredCapabilities; + BOOLEAN isDebugOnRestoreEnabled; } J9CRIUCheckpointState; #endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ @@ -5247,6 +5248,7 @@ typedef struct J9InternalVMFunctions { BOOLEAN (*isNonPortableRestoreMode)(struct J9VMThread *currentThread); BOOLEAN (*isJVMInPortableRestoreMode)(struct J9VMThread *currentThread); BOOLEAN (*isDebugOnRestoreEnabled)(struct J9JavaVM *vm); + BOOLEAN (*isDebugAgentDisabled)(struct J9JavaVM *vm); void (*setRequiredGhostFileLimit)(struct J9VMThread *currentThread, U_32 ghostFileLimit); BOOLEAN (*runInternalJVMCheckpointHooks)(struct J9VMThread *currentThread, const char **nlsMsgFormat); BOOLEAN (*runInternalJVMRestoreHooks)(struct J9VMThread *currentThread, const char **nlsMsgFormat); diff --git a/runtime/oti/vm_api.h b/runtime/oti/vm_api.h index 3d742913a6c..89d43d38e63 100644 --- a/runtime/oti/vm_api.h +++ b/runtime/oti/vm_api.h @@ -583,10 +583,30 @@ BOOLEAN isJVMInPortableRestoreMode(J9VMThread *currentThread); /** - * @brief Queries if debug on restore (specified via - * -XX:+DebugOnRestore) is supported. If so, the JVM - * will run in FSD mode pre-checkpoint and will transition out - * FSD mode on restore (unless debug is specified post restore). + * @brief This is a helper to query if debug on restore mode is enabled. + * + * A few use scenarios: + * 1. If CRIU is not enabled, FSD is disabled by default unless JDWP or some + * debug-specific flags/events are enabled/hooked, there is no notion of + * DebugOnRestore; + * 2. If CRIU is enabled (via -XX:+EnableCRIUSupport) but -XX:+DebugOnRestore + * is not specified, this is the same as use case #1; + * 3. If CRIU is enabled and -XX:+DebugOnRestore is specified, + * 3.1 If JDWP or some debug-specific flags/events are enabled/hooked, FSD + * mode is enabled, and JIT doesn't do any pre-emptive recompilation + * and debugging is enabled. + * 3.2 Otherwise FSD code is generated but FSD mode is not enabled, + * 3.2.1 If FSD is enabled via the post-restore option file, JIT will + * transmit to the interpreter as soon as possible, or VM triggers + * a transition via the FSD code generated pre-checkpoint; + * 3.2.2 Otherwise JIT throws all FSD code and uses the pre-emptively + * recompiled code in default mode. + * + * This helper method returns TRUE if CRIU is enabled, -XX:+DebugOnRestore is + * specified, JDWP is not enabled, and no debug-specific flags/events are + * enabled/hooked. JIT generates FSD code but FSD mode is not enabled. + * Otherwise, this returns FALSE, JIT checks if debug related flags/events are + * enabled/hooked and determines if FSD mode is to be enabled. * * @param vm javaVM token * @return TRUE if enabled, FALSE otherwise @@ -594,6 +614,16 @@ isJVMInPortableRestoreMode(J9VMThread *currentThread); BOOLEAN isDebugOnRestoreEnabled(J9JavaVM *vm); +/** + * @brief This is a helper to query if the debug agent is disabled. + * + * @param vm javaVM token + * @return TRUE if isDebugOnRestoreEnabled() and isCheckpointAllowed() return TRUE, + * FALSE otherwise + */ +BOOLEAN +isDebugAgentDisabled(J9JavaVM *vm); + /** * @brief Sets the maximum size for the CRIU ghost files. * If the new limit is smaller or equal to the previous limit, diff --git a/runtime/vm/CRIUHelpers.cpp b/runtime/vm/CRIUHelpers.cpp index a0d5b8ea978..929c5ab4dc2 100644 --- a/runtime/vm/CRIUHelpers.cpp +++ b/runtime/vm/CRIUHelpers.cpp @@ -178,9 +178,13 @@ isJVMInPortableRestoreMode(J9VMThread *currentThread) BOOLEAN isDebugOnRestoreEnabled(J9JavaVM *vm) { - return J9_ARE_NO_BITS_SET(vm->checkpointState.flags, J9VM_CRIU_IS_JDWP_ENABLED) - && J9_ARE_ALL_BITS_SET(vm->checkpointState.flags, J9VM_CRIU_SUPPORT_DEBUG_ON_RESTORE) - && isCRaCorCRIUSupportEnabled(vm); + return vm->checkpointState.isDebugOnRestoreEnabled; +} + +BOOLEAN +isDebugAgentDisabled(J9JavaVM *vm) +{ + return isCheckpointAllowed(vm) && vm->checkpointState.isDebugOnRestoreEnabled; } void diff --git a/runtime/vm/intfunc.c b/runtime/vm/intfunc.c index 9f2081a0ad3..63377c364a8 100644 --- a/runtime/vm/intfunc.c +++ b/runtime/vm/intfunc.c @@ -423,6 +423,7 @@ J9InternalVMFunctions J9InternalFunctions = { isNonPortableRestoreMode, isJVMInPortableRestoreMode, isDebugOnRestoreEnabled, + isDebugAgentDisabled, setRequiredGhostFileLimit, runInternalJVMCheckpointHooks, runInternalJVMRestoreHooks,