Mercurial > hg > truffle
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) { |