18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "gc_implementation/shared/vmGCOperations.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "prims/jvmtiExport.hpp"
31 #include "runtime/arguments.hpp"
32 #include "runtime/globals.hpp"
33 #include "runtime/java.hpp"
34 #include "runtime/javaCalls.hpp"
35 #include "runtime/os.hpp"
36 #include "services/attachListener.hpp"
37 #include "services/heapDumper.hpp"
38
39 volatile bool AttachListener::_initialized;
40
41 // Implementation of "properties" command.
42 //
43 // Invokes sun.misc.VMSupport.serializePropertiesToByteArray to serialize
44 // the system properties into a byte array.
45
46 static klassOop load_and_initialize_klass(Symbol* sh, TRAPS) {
47 klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
48 instanceKlassHandle ik (THREAD, k);
49 if (ik->should_be_initialized()) {
50 ik->initialize(CHECK_NULL);
51 }
52 return ik();
53 }
54
55 static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) {
56 Thread* THREAD = Thread::current();
57 HandleMark hm;
131 bool print_concurrent_locks = false;
132 if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {
133 print_concurrent_locks = true;
134 }
135
136 // thread stacks
137 VM_PrintThreads op1(out, print_concurrent_locks);
138 VMThread::execute(&op1);
139
140 // JNI global handles
141 VM_PrintJNI op2(out);
142 VMThread::execute(&op2);
143
144 // Deadlock detection
145 VM_FindDeadlocks op3(out);
146 VMThread::execute(&op3);
147
148 return JNI_OK;
149 }
150
151 #ifndef SERVICES_KERNEL // Heap dumping not supported
152 // Implementation of "dumpheap" command.
153 //
154 // Input arguments :-
155 // arg0: Name of the dump file
156 // arg1: "-live" or "-all"
157 jint dump_heap(AttachOperation* op, outputStream* out) {
158 const char* path = op->arg(0);
159 if (path == NULL || path[0] == '\0') {
160 out->print_cr("No dump file specified");
161 } else {
162 bool live_objects_only = true; // default is true to retain the behavior before this change is made
163 const char* arg1 = op->arg(1);
164 if (arg1 != NULL && (strlen(arg1) > 0)) {
165 if (strcmp(arg1, "-all") != 0 && strcmp(arg1, "-live") != 0) {
166 out->print_cr("Invalid argument to dumpheap operation: %s", arg1);
167 return JNI_ERR;
168 }
169 live_objects_only = strcmp(arg1, "-live") == 0;
170 }
349 out->print_cr("no such flag '%s'", name);
350 }
351 return JNI_OK;
352 }
353
354 // Table to map operation names to functions.
355
356 // names must be of length <= AttachOperation::name_length_max
357 static AttachOperationFunctionInfo funcs[] = {
358 { "agentProperties", get_agent_properties },
359 { "datadump", data_dump },
360 #ifndef SERVICES_KERNEL
361 { "dumpheap", dump_heap },
362 #endif // SERVICES_KERNEL
363 { "load", JvmtiExport::load_agent_library },
364 { "properties", get_system_properties },
365 { "threaddump", thread_dump },
366 { "inspectheap", heap_inspection },
367 { "setflag", set_flag },
368 { "printflag", print_flag },
369 { NULL, NULL }
370 };
371
372
373
374 // The Attach Listener threads services a queue. It dequeues an operation
375 // from the queue, examines the operation name (command), and dispatches
376 // to the corresponding function to perform the operation.
377
378 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) {
379 os::set_priority(thread, NearMaxPriority);
380
381 if (AttachListener::pd_init() != 0) {
382 return;
383 }
384 AttachListener::set_initialized();
385
386 for (;;) {
387 AttachOperation* op = AttachListener::dequeue();
388 if (op == NULL) {
|
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "gc_implementation/shared/vmGCOperations.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "prims/jvmtiExport.hpp"
31 #include "runtime/arguments.hpp"
32 #include "runtime/globals.hpp"
33 #include "runtime/java.hpp"
34 #include "runtime/javaCalls.hpp"
35 #include "runtime/os.hpp"
36 #include "services/attachListener.hpp"
37 #include "services/heapDumper.hpp"
38 #include "services/diagnosticCommand.hpp"
39
40 volatile bool AttachListener::_initialized;
41
42 // Implementation of "properties" command.
43 //
44 // Invokes sun.misc.VMSupport.serializePropertiesToByteArray to serialize
45 // the system properties into a byte array.
46
47 static klassOop load_and_initialize_klass(Symbol* sh, TRAPS) {
48 klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
49 instanceKlassHandle ik (THREAD, k);
50 if (ik->should_be_initialized()) {
51 ik->initialize(CHECK_NULL);
52 }
53 return ik();
54 }
55
56 static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) {
57 Thread* THREAD = Thread::current();
58 HandleMark hm;
132 bool print_concurrent_locks = false;
133 if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {
134 print_concurrent_locks = true;
135 }
136
137 // thread stacks
138 VM_PrintThreads op1(out, print_concurrent_locks);
139 VMThread::execute(&op1);
140
141 // JNI global handles
142 VM_PrintJNI op2(out);
143 VMThread::execute(&op2);
144
145 // Deadlock detection
146 VM_FindDeadlocks op3(out);
147 VMThread::execute(&op3);
148
149 return JNI_OK;
150 }
151
152 /**
153 * A jcmd attach operation request was received, which will now
154 * dispatch to the diagnostic commands used for serviceability functions.
155 */
156 static jint jcmd(AttachOperation* op, outputStream* out) {
157 Thread* THREAD = Thread::current();
158 // All the supplied jcmd arguments are stored as a single
159 // string (op->arg(0)). This is parsed by the Dcmd framework.
160 DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD);
161 if (HAS_PENDING_EXCEPTION) {
162 java_lang_Throwable::print(PENDING_EXCEPTION, out);
163 CLEAR_PENDING_EXCEPTION;
164 // The exception has been printed on the output stream
165 // If the JVM returns JNI_ERR, the attachAPI throws a generic I/O
166 // exception and the content of the output stream is not processed.
167 // By returning JNI_OK, the exception will be displayed on the client side
168 }
169 return JNI_OK;
170 }
171
172 #ifndef SERVICES_KERNEL // Heap dumping not supported
173 // Implementation of "dumpheap" command.
174 //
175 // Input arguments :-
176 // arg0: Name of the dump file
177 // arg1: "-live" or "-all"
178 jint dump_heap(AttachOperation* op, outputStream* out) {
179 const char* path = op->arg(0);
180 if (path == NULL || path[0] == '\0') {
181 out->print_cr("No dump file specified");
182 } else {
183 bool live_objects_only = true; // default is true to retain the behavior before this change is made
184 const char* arg1 = op->arg(1);
185 if (arg1 != NULL && (strlen(arg1) > 0)) {
186 if (strcmp(arg1, "-all") != 0 && strcmp(arg1, "-live") != 0) {
187 out->print_cr("Invalid argument to dumpheap operation: %s", arg1);
188 return JNI_ERR;
189 }
190 live_objects_only = strcmp(arg1, "-live") == 0;
191 }
370 out->print_cr("no such flag '%s'", name);
371 }
372 return JNI_OK;
373 }
374
375 // Table to map operation names to functions.
376
377 // names must be of length <= AttachOperation::name_length_max
378 static AttachOperationFunctionInfo funcs[] = {
379 { "agentProperties", get_agent_properties },
380 { "datadump", data_dump },
381 #ifndef SERVICES_KERNEL
382 { "dumpheap", dump_heap },
383 #endif // SERVICES_KERNEL
384 { "load", JvmtiExport::load_agent_library },
385 { "properties", get_system_properties },
386 { "threaddump", thread_dump },
387 { "inspectheap", heap_inspection },
388 { "setflag", set_flag },
389 { "printflag", print_flag },
390 { "jcmd", jcmd },
391 { NULL, NULL }
392 };
393
394
395
396 // The Attach Listener threads services a queue. It dequeues an operation
397 // from the queue, examines the operation name (command), and dispatches
398 // to the corresponding function to perform the operation.
399
400 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) {
401 os::set_priority(thread, NearMaxPriority);
402
403 if (AttachListener::pd_init() != 0) {
404 return;
405 }
406 AttachListener::set_initialized();
407
408 for (;;) {
409 AttachOperation* op = AttachListener::dequeue();
410 if (op == NULL) {
|