How to use gdb to debug C1 compiler's internal error?

Leslie Zhai lesliezhai at llvm.org.cn
Mon Mar 26 15:06:06 UTC 2018


Hi Andrew,

Thanks for your response!


在 2018年03月26日 17:48, Andrew Haley 写道:
> On 03/22/2018 04:32 PM, Leslie Zhai wrote:
>> So backtrace or set breakpoint might be helpful for debugging compiling
>> thread, but doesn't work for running thread? I am reading Analyzing and
>> Debugging the HotSpot VM at the OS Level[1] please give me some advice,
>> thanks a lot!
>>
>> [1] http://www.progdoc.de/papers/JavaOne2014/javaone2014_con3138.html
> You'll first need to set a breakpoint in the segfault handler here in
> JVM_handle_linux_signal:
>
>    VMError::report_and_die(t, sig, pc, info, ucVoid);
>
> Then you can use gdb to go up the stack to the point of the crash.
Work :)
(gdb) b VMError::report_and_die
Breakpoint 1 at 0x7ffff65c8f2c: VMError::report_and_die. (7 locations)
(gdb) r
Thread 14 "C1 CompilerThre" hit Breakpoint 1, VMError::report_and_die 
(thread=0x7ffff0220000,
     filename=0x7ffff66dd4c0 
"/home/xiangzhai/project/jdk/src/hotspot/share/utilities/growableArray.hpp", 

     lineno=230, message=0x7ffff66de828 "assert(0 <= i && i < _len) 
failed",
     detail_fmt=0x7ffff66de819 "illegal index", detail_args=0x7fffc89aafe8)
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/utilities/vmError.cpp:1244
1244      report_and_die(INTERNAL_ERROR, message, detail_fmt, 
detail_args, thread, NULL, NULL, NULL, filename, lineno, 0);
(gdb) bt
...
#3  0x00007ffff5ba4124 in GlobalValueNumbering::value_map_of 
(this=0x7fffc89ab300, block=0x7fff9c0135d0)
     at /home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_ValueMap.hpp:244
#4  0x00007ffff5ba4151 in GlobalValueNumbering::set_value_map_of 
(this=0x7fffc89ab300, block=0x7fff9c0135d0,
     map=0x7fff9c0142a0) at 
/home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_ValueMap.hpp:245
#5  0x00007ffff5ba3459 in GlobalValueNumbering::GlobalValueNumbering 
(this=0x7fffc89ab300, ir=0x7fffa0040c60)
     at /home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_ValueMap.cpp:514
#6  0x00007ffff5aa1812 in Compilation::build_hir (this=0x7fffc89ab610)
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_Compilation.cpp:204
#7  0x00007ffff5aa241f in Compilation::compile_java_method 
(this=0x7fffc89ab610)
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_Compilation.cpp:411
#8  0x00007ffff5aa284e in Compilation::compile_method (this=0x7fffc89ab610)
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_Compilation.cpp:484
#9  0x00007ffff5aa3007 in Compilation::Compilation (this=0x7fffc89ab610, 
compiler=0x7ffff021ad80,
     env=0x7fffc89ab9b0, method=0x7fff9c001a20, osr_bci=-1, 
buffer_blob=0x7fffd8fa0790,
     directive=0x7ffff01740f0) at 
/home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_Compilation.cpp:609
#10 0x00007ffff5aa68ef in Compiler::compile_method (this=0x7ffff021ad80, 
env=0x7fffc89ab9b0,
---Type <return> to continue, or q <return> to quit---
     method=0x7fff9c001a20, entry_bci=-1, directive=0x7ffff01740f0)
     at /home/xiangzhai/project/jdk/src/hotspot/share/c1/c1_Compiler.cpp:254
#11 0x00007ffff5cfdc54 in CompileBroker::invoke_compiler_on_method 
(task=0x7ffff0231b40)
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/compiler/compileBroker.cpp:1913
#12 0x00007ffff5cfcbbc in CompileBroker::compiler_thread_loop ()
     at 
/home/xiangzhai/project/jdk/src/hotspot/share/compiler/compileBroker.cpp:1618
...

It is helpful to find my careless bug:

diff -r 1f0838e3cebe src/hotspot/share/c1/c1_ValueMap.cpp
--- a/src/hotspot/share/c1/c1_ValueMap.cpp      Sat Mar 24 22:11:30 2018 
+0800
+++ b/src/hotspot/share/c1/c1_ValueMap.cpp      Mon Mar 26 22:37:22 2018 
+0800
@@ -486,14 +486,18 @@

  GlobalValueNumbering::GlobalValueNumbering(IR* ir)
    : _current_map(NULL)
-  , _value_maps(ir->linear_scan_order()->length(), 
ir->linear_scan_order()->length(), NULL)
+  , _value_maps(UseGreedy ? ir->greedy_order()->length() :
+                 ir->linear_scan_order()->length(),
+               UseGreedy ? ir->greedy_order()->length() :
+                 ir->linear_scan_order()->length(),
+               NULL)
    , _compilation(ir->compilation())
  {
    TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value 
numbering"));

    ShortLoopOptimizer short_loop_optimizer(this);

-  BlockList* blocks = ir->linear_scan_order();
+  BlockList* blocks = UseGreedy ? ir->greedy_order() : 
ir->linear_scan_order();
    int num_blocks = blocks->length();

    BlockBegin* start_block = blocks->at(0);
@@ -527,7 +531,8 @@
        assert(dominator == block->pred_at(0), "dominator must be equal 
to predecessor");
        // nothing to do here

-    } else if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
+    } else if (block->is_set(UseGreedy ? 
BlockBegin::greedy_loop_header_flag :
+ BlockBegin::linear_scan_loop_header_flag)) {
        // block has incoming backward branches -> try to optimize short 
loops
        if (!short_loop_optimizer.process(block)) {
          // loop is too complicated, so kill all memory loads because 
there might be
diff -r 1f0838e3cebe src/hotspot/share/c1/c1_ValueMap.hpp
--- a/src/hotspot/share/c1/c1_ValueMap.hpp      Sat Mar 24 22:11:30 2018 
+0800
+++ b/src/hotspot/share/c1/c1_ValueMap.hpp      Mon Mar 26 22:37:22 2018 
+0800
@@ -241,8 +241,8 @@
    // accessors
    Compilation*  compilation() const              { return _compilation; }
    ValueMap*     current_map()                    { return _current_map; }
-  ValueMap*     value_map_of(BlockBegin* block)  { return 
_value_maps.at(block->linear_scan_number()); }
-  void          set_value_map_of(BlockBegin* block, ValueMap* map)   { 
assert(value_map_of(block) == NULL, ""); 
_value_maps.at_put(block->linear_scan_number(), map); }
+  ValueMap*     value_map_of(BlockBegin* block)  { return 
_value_maps.at(UseGreedy ? block->greedy_number() : 
block->linear_scan_number()); }
+  void          set_value_map_of(BlockBegin* block, ValueMap* map)   { 
assert(value_map_of(block) == NULL, ""); _value_maps.at_put(UseGreedy ? 
block->greedy_number() : block->linear_scan_number(), map); }

    bool          is_processed(Value v)            { return 
_processed_values.contains(v); }
    void          set_processed(Value v)           { 
_processed_values.put(v); }


>
> At that point you'll be inspecting the stack to see what's there.  If
> you can't tell, then your next plan should be to instrument the code
> you're generating to add tracing information so that when it does, you
> know where you are.
>

Yes, it is not easy to debug, for example, wrongly modified X86's 
Runtime1::generate_handle_exception:

Thread 2 "java" received signal SIGSEGV, Segmentation fault.
0x00007fffe094e884 in ?? ()
(gdb) x /200i 0x00007fffe094e800
    0x7fffe094e800:      add    %al,(%rax)
    0x7fffe094e802:      add    %al,(%rax)
    0x7fffe094e804:      int3
    0x7fffe094e805:      int3
    0x7fffe094e806:      int3
    0x7fffe094e807:      int3
    0x7fffe094e808:      add    %al,(%rax)
    0x7fffe094e80a:      add    %al,(%rax)
    0x7fffe094e80c:      add    %al,(%rax)
    0x7fffe094e80e:      add    %al,(%rax)
    0x7fffe094e810:      loopne 0x7fffe094e813
    0x7fffe094e812:      add    %al,(%rax)
    0x7fffe094e814:      (bad)
    0x7fffe094e815:      (bad)
    0x7fffe094e816:      (bad)
    0x7fffe094e817:      (bad)
    0x7fffe094e818:      (bad)
    0x7fffe094e819:      (bad)
    0x7fffe094e81a:      (bad)
    0x7fffe094e81b:      dec    %esp
    0x7fffe094e81d:      int3
    0x7fffe094e81e:      int3
    0x7fffe094e81f:      int3
    0x7fffe094e820:      cmove  (%rax),%edx
    0x7fffe094e823:      xor    $0x2,%al
    0x7fffe094e825:      lock or %ecx,%esp
    0x7fffe094e828:      adc    $0x10640ab0,%eax
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e82d:      fs adc $0x64,%al
    0x7fffe094e830:      or     $0x64,%al
    0x7fffe094e832:      or     %eax,(%rax)
    0x7fffe094e834:      add    %edi,%eax
    0x7fffe094e836:      icebp
    0x7fffe094e837:      incl   (%rax)
    0x7fffe094e839:      push   %rax
    0x7fffe094e83a:      add    %al,%al
    0x7fffe094e83c:      or     -0x8(%rcx,%rax,1),%ah
    0x7fffe094e840:      loope  0x7fffe094e841
    0x7fffe094e842:      add    $0xac00050,%eax
    0x7fffe094e847:      fs add $0x640f64,%eax
    0x7fffe094e84d:      add    %al,(%rax)
    0x7fffe094e84f:      add    %cl,%ah
    0x7fffe094e851:      int3
    0x7fffe094e852:      int3
    0x7fffe094e853:      int3
    0x7fffe094e854:      int3
    0x7fffe094e855:      int3
    0x7fffe094e856:      int3
    0x7fffe094e857:      int3
    0x7fffe094e858:      int3
    0x7fffe094e859:      int3
    0x7fffe094e85a:      int3
    0x7fffe094e85b:      int3
    0x7fffe094e85c:      int3
    0x7fffe094e85d:      int3
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e85e:      int3
    0x7fffe094e85f:      int3
    0x7fffe094e860:      mov    %eax,-0x16000(%rsp)
    0x7fffe094e867:      push   %rbp
    0x7fffe094e868:      sub    $0x10,%rsp
    0x7fffe094e86c:      mov    %rsi,%rbp
    0x7fffe094e86f:      callq  0x7fffd9661ea0
    0x7fffe094e874:      test   %rax,%rax
    0x7fffe094e877:      je     0x7fffe094e8a1
    0x7fffe094e879:      mov    %rax,%rsi
    0x7fffe094e87c:      mov    %rbp,%rdx
    0x7fffe094e87f:      callq  0x7fffd96624c0
=> 0x7fffe094e884:      mov    0x8(%rax),%r10d
    0x7fffe094e888:      cmp    $0x200002dd,%r10d
    0x7fffe094e88f:      jne    0x7fffe094e8ae
    0x7fffe094e891:      add    $0x10,%rsp
    0x7fffe094e895:      pop    %rbp
    0x7fffe094e896:      mov    0x80(%r15),%r10
    0x7fffe094e89d:      test   %eax,(%r10)
    0x7fffe094e8a0:      retq
    0x7fffe094e8a1:      mov    $0xfffffff6,%esi
    0x7fffe094e8a6:      nop
    0x7fffe094e8a7:      callq  0x7fffd8ec7220
    0x7fffe094e8ac:      ud2
    0x7fffe094e8ae:      mov    $0xffffffde,%esi
    0x7fffe094e8b3:      mov    %rax,%rbp
    0x7fffe094e8b6:      nop
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e8b7:      callq  0x7fffd8ec7220
    0x7fffe094e8bc:      ud2
    0x7fffe094e8be:      mov    %rax,%rsi
    0x7fffe094e8c1:      jmp    0x7fffe094e8c6
    0x7fffe094e8c3:      mov    %rax,%rsi
    0x7fffe094e8c6:      add    $0x10,%rsp
    0x7fffe094e8ca:      pop    %rbp
    0x7fffe094e8cb:      jmpq   0x7fffd903b7a0
    0x7fffe094e8d0:      mov    $0xfffffff4,%esi
    0x7fffe094e8d5:      nop
    0x7fffe094e8d6:      nop
    0x7fffe094e8d7:      callq  0x7fffd8ec7220
    0x7fffe094e8dc:      ud2
    0x7fffe094e8de:      hlt
    0x7fffe094e8df:      hlt
    0x7fffe094e8e0:      movabs $0x0,%rbx
    0x7fffe094e8ea:      jmpq   0x7fffe094e8ea
    0x7fffe094e8ef:      movabs $0x0,%rbx
    0x7fffe094e8f9:      jmpq   0x7fffe094e8f9
    0x7fffe094e8fe:      jmpq   0x7fffd902dfa0
    0x7fffe094e903:      callq  0x7fffe094e908
    0x7fffe094e908:      subq   $0x5,(%rsp)
    0x7fffe094e90d:      jmpq   0x7fffd8ec6c60
    0x7fffe094e912:      hlt
    0x7fffe094e913:      hlt
    0x7fffe094e914:      hlt
    0x7fffe094e915:      hlt
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e916:      hlt
    0x7fffe094e917:      hlt
    0x7fffe094e918:      nop
    0x7fffe094e919:      push   %rbp
    0x7fffe094e91a:      xor    %cl,%cl
    0x7fffe094e91c:      (bad)
    0x7fffe094e91d:      jg     0x7fffe094e91f
    0x7fffe094e91f:      add    %ch,%al
    0x7fffe094e921:      (bad)
    0x7fffe094e922:      add    %al,(%rax)
    0x7fffe094e924:      add    %eax,(%rax)
    0x7fffe094e926:      add    %al,(%rax)
    0x7fffe094e928:      sub    $0x13,%bh
    0x7fffe094e92b:      leaveq
    0x7fffe094e92c:      (bad)
    0x7fffe094e92d:      jg     0x7fffe094e92f
    0x7fffe094e92f:      add    %bh,%bh
    0x7fffe094e931:      add    %al,(%rcx)
    0x7fffe094e933:      add    %al,(%rax)
    0x7fffe094e935:      add    %al,(%rax)
    0x7fffe094e937:      add    %eax,(%rax)
    0x7fffe094e939:      rolb   %cl,(%rdx)
    0x7fffe094e93b:      add    %al,(%rcx)
    0x7fffe094e93d:      add    %eax,(%rdi)
    0x7fffe094e93f:      add    %al,(%rax)
    0x7fffe094e941:      add    %eax,(%rax)
    0x7fffe094e943:      add    %al,(%rax)
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e945:      add    %eax,0x11(%rip)        # 0x7fffe094e95c
    0x7fffe094e94b:      add    %ecx,(%rax)
    0x7fffe094e94d:      add    %al,(%rax)
    0x7fffe094e94f:      add    %al,(%rdx)
    0x7fffe094e951:      add    (%rax),%al
    0x7fffe094e953:      add    %dl,%dl
    0x7fffe094e955:      add    (%rax),%al
    0x7fffe094e957:      add    %eax,0x2011(%rip)        # 0x7fffe095096e
    0x7fffe094e95d:      add    %eax,0x0(%rip)        # 0x7fffe094e963
    0x7fffe094e963:      add    %ecx,(%rax)
    0x7fffe094e965:      adc    %eax,(%rdi)
    0x7fffe094e967:      add    %al,(%rax)
    0x7fffe094e969:      add    %eax,(%rcx)
    0x7fffe094e96b:      add    %al,(%rax)
    0x7fffe094e96d:      add    %al,(%rcx)
    0x7fffe094e96f:      add    (%rax),%al
    0x7fffe094e971:      add    %al,(%rcx)
    0x7fffe094e973:      or     %dl,(%rcx)
    0x7fffe094e975:      ds add %cl,%ah
    0x7fffe094e978:      (bad)
    0x7fffe094e979:      (bad)
    0x7fffe094e97a:      (bad)
    0x7fffe094e97b:      incl   (%rax)
    0x7fffe094e97d:      add    %al,(%rax)
    0x7fffe094e97f:      add    %al,(%rax)
    0x7fffe094e981:      add    %al,(%rax)
    0x7fffe094e983:      add    %al,(%rax)
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e985:      add    %al,(%rax)
    0x7fffe094e987:      add    %cl,(%rax,%rax,1)
    0x7fffe094e98a:      add    %al,(%rax)
    0x7fffe094e98c:      add    %eax,(%rax)
    0x7fffe094e98e:      add    %al,(%rax)
    0x7fffe094e990:      add    %al,(%rax)
    0x7fffe094e992:      add    %al,(%rax)
    0x7fffe094e994:      add    %al,(%rax)
    0x7fffe094e996:      add    %al,(%rax)
    0x7fffe094e998:      adc    $0x0,%al
    0x7fffe094e99a:      add    %al,(%rax)
    0x7fffe094e99c:      or     (%rax),%eax
    0x7fffe094e99e:      add    %al,(%rax)
    0x7fffe094e9a0:      add    %al,(%rax)
    0x7fffe094e9a2:      add    %al,(%rax)
    0x7fffe094e9a4:      add    $0x0,%al
    0x7fffe094e9a6:      add    %al,(%rax)
    0x7fffe094e9a8:      and    $0x0,%al
    0x7fffe094e9aa:      add    %al,(%rax)
    0x7fffe094e9ac:      adc    $0x0,%al
    0x7fffe094e9ae:      add    %al,(%rax)
    0x7fffe094e9b0:      add    %al,(%rax)
    0x7fffe094e9b2:      add    %al,(%rax)
    0x7fffe094e9b4:      add    $0x0,%al
    0x7fffe094e9b6:      add    %al,(%rax)
    0x7fffe094e9b8:      xor    %eax,(%rax)
    0x7fffe094e9ba:      add    %al,(%rax)
---Type <return> to continue, or q <return> to quit---
    0x7fffe094e9bc:      sbb    (%rax),%al
    0x7fffe094e9be:      add    %al,(%rax)
    0x7fffe094e9c0:      add    %al,(%rax)
    0x7fffe094e9c2:      add    %al,(%rax)
    0x7fffe094e9c4:      add    %al,(%rax)
    0x7fffe094e9c6:      add    %al,(%rax)
    0x7fffe094e9c8:      rex.WR add %r8b,(%rax)
    0x7fffe094e9cb:      add    %ah,(%rsi)
    0x7fffe094e9cd:      add    %al,(%rax)
    0x7fffe094e9cf:      add    %al,(%rax)
    0x7fffe094e9d1:      add    %al,(%rax)

Then how to add tracing information to find the WHERE? please give me 
some hint, thanks a lot!

diff -r 1f0838e3cebe src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp   Sat Mar 24 22:11:30 2018 
+0800
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp   Mon Mar 26 23:04:12 2018 
+0800
@@ -750,7 +750,6 @@

      // Pop the return address.
      __ leave();
-    __ pop(rcx);
      __ jmp(rcx);  // jump to exception handler
      break;
    default:  ShouldNotReachHere();

-- 
Regards,
Leslie Zhai





More information about the hotspot-compiler-dev mailing list