21 * questions.
22 *
23 */
24
25 #include "classfile/javaClasses.inline.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "jfr/dcmd/jfrDcmds.hpp"
28 #include "jfr/jfr.hpp"
29 #include "jfr/jni/jfrJavaSupport.hpp"
30 #include "jfr/periodic/jfrRedactedEvents.hpp"
31 #include "jfr/recorder/jfrRecorder.hpp"
32 #include "jfr/recorder/service/jfrOptionSet.hpp"
33 #include "jfr/support/jfrThreadLocal.hpp"
34 #include "logging/log.hpp"
35 #include "logging/logConfiguration.hpp"
36 #include "logging/logMessage.hpp"
37 #include "memory/arena.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/symbol.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/jniHandles.hpp"
44 #include "services/diagnosticArgument.hpp"
45 #include "services/diagnosticFramework.hpp"
46 #include "utilities/globalDefinitions.hpp"
47
48
49 bool register_jfr_dcmds() {
50 uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
51 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export));
52 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export));
53 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export));
54 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export));
55 // JFR.query Uncomment when developing new queries for the JFR.view command
56 // DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrQueryFlightRecordingDCmd>(full_export, /*hidden=*/true));
57 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrViewFlightRecordingDCmd>(full_export));
58 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export));
59 return true;
60 }
96 }
97
98 static void handle_pending_exception(outputStream* output, bool startup, oop throwable) {
99 assert(throwable != nullptr, "invariant");
100
101 oop msg = java_lang_Throwable::message(throwable);
102 if (msg == nullptr) {
103 return;
104 }
105 char* text = java_lang_String::as_utf8_string(msg);
106 if (text != nullptr) {
107 if (startup) {
108 log_error(jfr,startup)("%s", text);
109 } else {
110 output->print_cr("%s", text);
111 }
112 }
113 }
114
115 static void print_message(outputStream* output, oop content, TRAPS) {
116 objArrayOop lines = objArrayOop(content);
117 assert(lines != nullptr, "invariant");
118 assert(lines->is_array(), "must be array");
119 const int length = lines->length();
120 for (int i = 0; i < length; ++i) {
121 const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
122 if (text == nullptr) {
123 // An oome has been thrown and is pending.
124 break;
125 }
126 output->print_cr("%s", text);
127 }
128 }
129
130 static void log(oop content, TRAPS) {
131 LogMessage(jfr,startup) msg;
132 objArrayOop lines = objArrayOop(content);
133 assert(lines != nullptr, "invariant");
134 assert(lines->is_array(), "must be array");
135 const int length = lines->length();
136 for (int i = 0; i < length; ++i) {
137 const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
138 if (text == nullptr) {
139 // An oome has been thrown and is pending.
140 break;
141 }
142 msg.info("%s", text);
143 }
144 }
145
146 static void handle_dcmd_result(outputStream* output,
147 const oop result,
148 const DCmdSource source,
149 TRAPS) {
150 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
151 assert(output != nullptr, "invariant");
152 ResourceMark rm(THREAD);
153 const bool startup = DCmd_Source_Internal == source;
154 if (HAS_PENDING_EXCEPTION) {
336
337 GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
338 static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
339 JavaThread* thread = JavaThread::current();
340 GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
341 JavaValue result(T_OBJECT);
342 JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
343 invoke(getArgumentInfos, thread);
344 if (thread->has_pending_exception()) {
345 // Most likely an OOME, but the DCmdFramework is not the best place to handle it.
346 // We handle it locally by clearing the exception and returning an array with dummy descriptors.
347 // This lets the MBean server initialization routine complete successfully,
348 // but this particular command will have no argument descriptors exposed.
349 // Hence we postpone, or delegate, handling of OOME's to code that is better suited.
350 log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
351 thread->clear_pending_exception();
352 initialize_dummy_descriptors(array);
353 assert(array->length() == _num_arguments, "invariant");
354 return array;
355 }
356 objArrayOop arguments = objArrayOop(result.get_oop());
357 assert(arguments != nullptr, "invariant");
358 assert(arguments->is_array(), "must be array");
359 const int num_arguments = arguments->length();
360 assert(num_arguments == _num_arguments, "invariant");
361 prepare_dcmd_string_arena(thread);
362 for (int i = 0; i < num_arguments; ++i) {
363 DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
364 assert(dai != nullptr, "invariant");
365 array->append(dai);
366 }
367 return array;
368 }
369
370 GrowableArray<const char*>* JfrDCmd::argument_name_array() const {
371 GrowableArray<DCmdArgumentInfo*>* argument_infos = argument_info_array();
372 GrowableArray<const char*>* array = new GrowableArray<const char*>(argument_infos->length());
373 for (int i = 0; i < argument_infos->length(); i++) {
374 array->append(argument_infos->at(i)->name());
375 }
376 return array;
377 }
378
|
21 * questions.
22 *
23 */
24
25 #include "classfile/javaClasses.inline.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "jfr/dcmd/jfrDcmds.hpp"
28 #include "jfr/jfr.hpp"
29 #include "jfr/jni/jfrJavaSupport.hpp"
30 #include "jfr/periodic/jfrRedactedEvents.hpp"
31 #include "jfr/recorder/jfrRecorder.hpp"
32 #include "jfr/recorder/service/jfrOptionSet.hpp"
33 #include "jfr/support/jfrThreadLocal.hpp"
34 #include "logging/log.hpp"
35 #include "logging/logConfiguration.hpp"
36 #include "logging/logMessage.hpp"
37 #include "memory/arena.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/oopCast.inline.hpp"
42 #include "oops/symbol.hpp"
43 #include "runtime/handles.inline.hpp"
44 #include "runtime/jniHandles.hpp"
45 #include "services/diagnosticArgument.hpp"
46 #include "services/diagnosticFramework.hpp"
47 #include "utilities/globalDefinitions.hpp"
48
49
50 bool register_jfr_dcmds() {
51 uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
52 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export));
53 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export));
54 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export));
55 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export));
56 // JFR.query Uncomment when developing new queries for the JFR.view command
57 // DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrQueryFlightRecordingDCmd>(full_export, /*hidden=*/true));
58 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrViewFlightRecordingDCmd>(full_export));
59 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export));
60 return true;
61 }
97 }
98
99 static void handle_pending_exception(outputStream* output, bool startup, oop throwable) {
100 assert(throwable != nullptr, "invariant");
101
102 oop msg = java_lang_Throwable::message(throwable);
103 if (msg == nullptr) {
104 return;
105 }
106 char* text = java_lang_String::as_utf8_string(msg);
107 if (text != nullptr) {
108 if (startup) {
109 log_error(jfr,startup)("%s", text);
110 } else {
111 output->print_cr("%s", text);
112 }
113 }
114 }
115
116 static void print_message(outputStream* output, oop content, TRAPS) {
117 assert(content != nullptr, "invariant");
118 refArrayOop lines = oop_cast<refArrayOop>(content);
119 const int length = lines->length();
120 for (int i = 0; i < length; ++i) {
121 const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
122 if (text == nullptr) {
123 // An oome has been thrown and is pending.
124 break;
125 }
126 output->print_cr("%s", text);
127 }
128 }
129
130 static void log(oop content, TRAPS) {
131 LogMessage(jfr,startup) msg;
132 assert(content != nullptr, "invariant");
133 refArrayOop lines = oop_cast<refArrayOop>(content);
134 const int length = lines->length();
135 for (int i = 0; i < length; ++i) {
136 const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
137 if (text == nullptr) {
138 // An oome has been thrown and is pending.
139 break;
140 }
141 msg.info("%s", text);
142 }
143 }
144
145 static void handle_dcmd_result(outputStream* output,
146 const oop result,
147 const DCmdSource source,
148 TRAPS) {
149 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
150 assert(output != nullptr, "invariant");
151 ResourceMark rm(THREAD);
152 const bool startup = DCmd_Source_Internal == source;
153 if (HAS_PENDING_EXCEPTION) {
335
336 GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
337 static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
338 JavaThread* thread = JavaThread::current();
339 GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
340 JavaValue result(T_OBJECT);
341 JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
342 invoke(getArgumentInfos, thread);
343 if (thread->has_pending_exception()) {
344 // Most likely an OOME, but the DCmdFramework is not the best place to handle it.
345 // We handle it locally by clearing the exception and returning an array with dummy descriptors.
346 // This lets the MBean server initialization routine complete successfully,
347 // but this particular command will have no argument descriptors exposed.
348 // Hence we postpone, or delegate, handling of OOME's to code that is better suited.
349 log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
350 thread->clear_pending_exception();
351 initialize_dummy_descriptors(array);
352 assert(array->length() == _num_arguments, "invariant");
353 return array;
354 }
355 oop oop_args = result.get_oop();
356 assert(oop_args != nullptr, "invariant");
357 refArrayOop arguments = oop_cast<refArrayOop>(oop_args);
358 const int num_arguments = arguments->length();
359 assert(num_arguments == _num_arguments, "invariant");
360 prepare_dcmd_string_arena(thread);
361 for (int i = 0; i < num_arguments; ++i) {
362 DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
363 assert(dai != nullptr, "invariant");
364 array->append(dai);
365 }
366 return array;
367 }
368
369 GrowableArray<const char*>* JfrDCmd::argument_name_array() const {
370 GrowableArray<DCmdArgumentInfo*>* argument_infos = argument_info_array();
371 GrowableArray<const char*>* array = new GrowableArray<const char*>(argument_infos->length());
372 for (int i = 0; i < argument_infos->length(); i++) {
373 array->append(argument_infos->at(i)->name());
374 }
375 return array;
376 }
377
|