comparison agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @ 6972:bd7a7ce2e264

6830717: replay of compilations would help with debugging Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method. Reviewed-by: kvn, twisti, sspitsyn Contributed-by: yumin.qi@oracle.com
author minqi
date Mon, 12 Nov 2012 14:03:53 -0800
parents 5a98bf7d847b
children 39432a1cefdd
comparison
equal deleted inserted replaced
6965:3be318ecfae5 6972:bd7a7ce2e264
31 31
32 import sun.jvm.hotspot.types.Type; 32 import sun.jvm.hotspot.types.Type;
33 import sun.jvm.hotspot.types.Field; 33 import sun.jvm.hotspot.types.Field;
34 import sun.jvm.hotspot.HotSpotTypeDataBase; 34 import sun.jvm.hotspot.HotSpotTypeDataBase;
35 import sun.jvm.hotspot.types.basic.BasicType; 35 import sun.jvm.hotspot.types.basic.BasicType;
36 import sun.jvm.hotspot.types.basic.BasicTypeDataBase;
36 import sun.jvm.hotspot.types.CIntegerType; 37 import sun.jvm.hotspot.types.CIntegerType;
37 import sun.jvm.hotspot.code.*; 38 import sun.jvm.hotspot.code.*;
38 import sun.jvm.hotspot.compiler.*; 39 import sun.jvm.hotspot.compiler.*;
39 import sun.jvm.hotspot.debugger.*; 40 import sun.jvm.hotspot.debugger.*;
40 import sun.jvm.hotspot.interpreter.*; 41 import sun.jvm.hotspot.interpreter.*;
443 } 444 }
444 } 445 }
445 if (needsPrintln) { 446 if (needsPrintln) {
446 out.println(); 447 out.println();
447 } 448 }
449 }
450 }
451 },
452 new Command("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
453 // This is used to dump replay data from ciInstanceKlass, ciMethodData etc
454 // default file name is replay.txt, also if java crashes in compiler
455 // thread, this file will be dumped in error processing.
456 public void doit(Tokens t) {
457 if (t.countTokens() != 1) {
458 usage();
459 return;
460 }
461 String name = t.nextToken();
462 Address a = null;
463 try {
464 a = VM.getVM().getDebugger().parseAddress(name);
465 } catch (NumberFormatException e) { }
466 if (a != null) {
467 // only nmethod, Method, MethodData and InstanceKlass needed to
468 // dump replay data
469
470 CodeBlob cb = VM.getVM().getCodeCache().findBlob(a);
471 if (cb != null && (cb instanceof NMethod)) {
472 ((NMethod)cb).dumpReplayData(out);
473 return;
474 }
475 // assume it is Metadata
476 Metadata meta = Metadata.instantiateWrapperFor(a);
477 if (meta != null) {
478 meta.dumpReplayData(out);
479 } else {
480 usage();
481 return;
482 }
483 }
484 // Not an address
485 boolean all = name.equals("-a");
486 Threads threads = VM.getVM().getThreads();
487 for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
488 ByteArrayOutputStream bos = new ByteArrayOutputStream();
489 thread.printThreadIDOn(new PrintStream(bos));
490 if (all || bos.toString().equals(name)) {
491 if (thread instanceof CompilerThread) {
492 CompilerThread ct = (CompilerThread)thread;
493 ciEnv env = ct.env();
494 if (env != null) {
495 env.dumpReplayData(out);
496 }
497 }
498 }
499 }
500 }
501 },
502 new Command("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
503 // This is used to dump jar files of all the classes
504 // loaded in the core. Everything on the bootclasspath
505 // will go in boot.jar and everything else will go in
506 // app.jar. Then the classes can be loaded by the replay
507 // jvm using -Xbootclasspath/p:boot.jar -cp app.jar. boot.jar usually
508 // not needed, unless changed by jvmti.
509 public void doit(Tokens t) {
510 int tcount = t.countTokens();
511 if (tcount > 2) {
512 usage();
513 return;
514 }
515 try {
516 String prefix = "";
517 String option = "all"; // default
518 switch(tcount) {
519 case 0:
520 break;
521 case 1:
522 option = t.nextToken();
523 if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
524 !option.equalsIgnoreCase("root")) {
525 prefix = option;
526 option = "all";
527 }
528 break;
529 case 2:
530 option = t.nextToken();
531 prefix = t.nextToken();
532 break;
533 default:
534 usage();
535 return;
536 }
537 if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
538 !option.equalsIgnoreCase("boot")) {
539 usage();
540 return;
541 }
542 ClassDump cd = new ClassDump();
543 if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("boot")) {
544 cd.setClassFilter(new BootFilter());
545 cd.setJarOutput(prefix + "boot.jar");
546 cd.run();
547 }
548 if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("app")) {
549 cd.setClassFilter(new NonBootFilter());
550 cd.setJarOutput(prefix + "app.jar");
551 cd.run();
552 }
553 } catch (IOException ioe) {
554 ioe.printStackTrace();
448 } 555 }
449 } 556 }
450 }, 557 },
451 new Command("findpc", "findpc address", false) { 558 new Command("findpc", "findpc address", false) {
452 public void doit(Tokens t) { 559 public void doit(Tokens t) {