@@ -1330,6 +1330,44 @@ cbVMDeath(jvmtiEnv *jvmti_env, JNIEnv *env)
13301330 LOG_MISC (("END cbVMDeath" ));
13311331}
13321332
1333+ /**
1334+ * Event callback for JVMTI_EVENT_DATA_DUMP_REQUEST
1335+ *
1336+ * This callback is made when a JVMTI data dump is requested. The common way of doing
1337+ * this is with "jcmd <pid> JVMTI.data_dump".
1338+ *
1339+ * Debug agent data dumps are experimental and only intended to be used by debug agent
1340+ * developers. Data dumps are disabled by default.
1341+ *
1342+ * This callback is enabled by launching the debug agent with datadump=y. The easiest
1343+ * way to enabled data dumps with debugger tests or when using jdb is to use the
1344+ * _JAVA_JDWP_OPTIONS export. The following works well when running tests:
1345+ *
1346+ * make test TEST=<test> \
1347+ * JTREG='JAVA_OPTIONS=-XX:+StartAttachListener;OPTIONS=-e:_JAVA_JDWP_OPTIONS=datadump=y'
1348+ *
1349+ * Data dumps may fail to happen due to the debug agent suspending all threads.
1350+ * This causes the Signal Dispatcher and Attach Listener threads to be suspended,
1351+ * which can cause issues with jcmd attaching. Running with -XX:+StartAttachListener can
1352+ * help, but in general it is best not to try a datadump when all threads are suspended.
1353+ *
1354+ * Data dumps are also risky when the debug agent is handling events or commands from
1355+ * the debugger, due to dumping data that is not lock protected. This can cause a
1356+ * crash.
1357+ *
1358+ * Data dumps are meant to aid with post mortem debugging (debugging after a
1359+ * problem has been detected), not for ongoing periodic data gathering.
1360+ */
1361+ static void JNICALL
1362+ cbDataDump (jvmtiEnv * jvmti_env )
1363+ {
1364+ tty_message ("Debug Agent Data Dump" );
1365+ tty_message ("=== START DUMP ===" );
1366+ threadControl_dumpAllThreads ();
1367+ eventHandler_dumpAllHandlers (JNI_TRUE );
1368+ tty_message ("=== END DUMP ===" );
1369+ }
1370+
13331371/**
13341372 * Delete this handler (do not delete permanent handlers):
13351373 * Deinsert handler from active list,
@@ -1518,6 +1556,19 @@ eventHandler_initialize(jbyte sessionID)
15181556 if (error != JVMTI_ERROR_NONE ) {
15191557 EXIT_ERROR (error ,"Can't enable garbage collection finish events" );
15201558 }
1559+
1560+ /*
1561+ * DATA_DUMP_REQUEST is special since it is not tied to any handlers or an EI,
1562+ * so it cannot be setup using threadControl_setEventMode(). Use JVMTI API directly.
1563+ */
1564+ if (gdata -> jvmti_data_dump ) {
1565+ error = JVMTI_FUNC_PTR (gdata -> jvmti ,SetEventNotificationMode )
1566+ (gdata -> jvmti , JVMTI_ENABLE , JVMTI_EVENT_DATA_DUMP_REQUEST , NULL );
1567+ if (error != JVMTI_ERROR_NONE ) {
1568+ EXIT_ERROR (error ,"Can't enable data dump request events" );
1569+ }
1570+ }
1571+
15211572 /*
15221573 * Only enable vthread START and END events if we want to remember
15231574 * vthreads when no debugger is connected.
@@ -1580,6 +1631,8 @@ eventHandler_initialize(jbyte sessionID)
15801631 gdata -> callbacks .VirtualThreadStart = & cbVThreadStart ;
15811632 /* Event callback for JVMTI_EVENT_VIRTUAL_THREAD_END */
15821633 gdata -> callbacks .VirtualThreadEnd = & cbVThreadEnd ;
1634+ /* Event callback for JVMTI_EVENT_DATA_DUMP_REQUEST */
1635+ gdata -> callbacks .DataDumpRequest = & cbDataDump ;
15831636
15841637 error = JVMTI_FUNC_PTR (gdata -> jvmti ,SetEventCallbacks )
15851638 (gdata -> jvmti , & (gdata -> callbacks ), sizeof (gdata -> callbacks ));
@@ -1851,9 +1904,7 @@ eventHandler_installExternal(HandlerNode *node)
18511904 JNI_TRUE );
18521905}
18531906
1854- /***** debugging *****/
1855-
1856- #ifdef DEBUG
1907+ /***** APIs for debugging the debug agent *****/
18571908
18581909void
18591910eventHandler_dumpAllHandlers (jboolean dumpPermanent )
@@ -1892,5 +1943,3 @@ eventHandler_dumpHandler(HandlerNode *node)
18921943 tty_message ("Handler for %s(%d)\n" , eventIndex2EventName (node -> ei ), node -> ei );
18931944 eventFilter_dumpHandlerFilters (node );
18941945}
1895-
1896- #endif /* DEBUG */
0 commit comments