2011-06-23 4 views
16

何らかの競合状態のような感じで、 の生産で時々セグメンテーションフォルトが発生するとJVMがクラッシュします。再現するSun JVM(JRE jre1.6.0_24)segfault NET_Read

セットアップ: - LinuxのUbuntuの9.10とDebian 4.xの64ビットのマルチコアAMD 上のJREのjre1.6.0_24 - ApacheのTomcatを6.0.24 ... 6.0.32

fastdebugのを再生してJavaを再コンパイル問題(このgcc -g1) しかし、我々は がここに持っているものよりもはるかに有用な情報をもたらさない。

デバッグでjavaを再コンパイルしても、問題が再現されません(これは gcc -gとおそらくいくつかの-DSOMETHINGコードのデバッグフラグです)。

これを理解するための助けがあれば、最も感謝します。

コアファイルは、Oracleから1.6.0_24 jdkを使用して生成されました。 gdbが表示されます:

Program terminated with signal 11, Segmentation fault. 
    #0 0x00002aaab7b10666 in NET_Read() from 
    /usr/local/jdk1.6.0_24/jre/lib/amd64/libnet.so 

私のアセンブリは本当に本当に本当に錆びています。念頭に置いていることを維持:

そこにデータを見てみると
0x4b3dffc8 

::だから

(gdb) info frame 
    Stack level 0, frame at 0x4b3e0040: 
    rip = 0x2aaab7b10666 in NET_Read; saved rip 0x2aaab7b0d53b 
    called by frame at 0x4b3f0090 
      Arglist at 0x4b3dffc8, args: 
    Locals at 0x4b3dffc8, Previous frame's sp is 0x4b3e0040 
    Saved registers: 
    rbx at 0x4b3e0008, rbp at 0x4b3e0010, r12 at 0x4b3e0018, r13 at 
    0x4b3e0020, r14 at 0x4b3e0028, r15 at 0x4b3e0030, rip at 0x4b3e0038 

、GDBは、引数リストがであることを教えてくれる

(gdb) x/8x 0x4b3dffc8 
    0x4b3dffc8:  0x00000000  0x00000000  0x00000000  0x00000000 
    0x4b3dffd8:  0x00000000  0x00000000  0x00000000  0x00000000 

`

をので、そこにはサイコロはありません。繰り返しになりますが、私の議論は2番目のwaveスカにまでさかのぼります。したがって、 は、スタックが幾分ぶち壊されていると思うか、gcc 最適化フラグがスタックの代わりに引数 のレジスタを使用するコードを生成しますか?

jdk/src/solaris/native/java/net/linux_close.c 

    *snip* 
    /* 
      * Macro to perform a blocking IO operation. Restarts 
    * automatically if interrupted by signal (other than 
      * our wakeup signal) 
    */ 
    #define BLOCKING_IO_RETURN_INT(FD, FUNC) {  \ 
     int ret;         \ 
     threadEntry_t self;       \ 
       fdEntry_t *fdEntry = getFdEntry(FD);  \ 
       if (fdEntry == NULL) {      \ 
      errno = EBADF;       \ 
      return -1;        \ 
     }           \ 
     do {          \ 
      startOp(fdEntry, &self);    \ 
      ret = FUNC;        \ 
      endOp(fdEntry, &self);     \ 
     } while (ret == -1 && errno == EINTR);  \ 
     return ret;         \ 
    } 

    int NET_Read(int s, void* buf, size_t len) { 
     BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, 0)); 
    } 
:NETReadのソースコードを見てみると

0x00002aaab7b10650 <NET_Read+0>:  push %r15 
      0x00002aaab7b10652 <NET_Read+2>:  mov %rdx,%r15 
    0x00002aaab7b10655 <NET_Read+5>:  push %r14 
          0x00002aaab7b10657 <NET_Read+7>:  push %r13 
    0x00002aaab7b10659 <NET_Read+9>:  mov %edi,%r13d 
    0x00002aaab7b1065c <NET_Read+12>:  push %r12 
    0x00002aaab7b1065e <NET_Read+14>:  push %rbp 
    0x00002aaab7b1065f <NET_Read+15>:  push %rbx 
    0x00002aaab7b10660 <NET_Read+16>:  sub $0x38,%rsp 
    0x00002aaab7b10664 <NET_Read+20>:  test %edi,%edi 
    0x00002aaab7b10666 <NET_Read+22>:  mov %rsi,0x8(%rsp) 
    0x00002aaab7b1066b <NET_Read+27>:  js  0x2aaab7b1067c <NET_Read+44> 
    0x00002aaab7b1066d <NET_Read+29>:  lea 1073812(%rip),%rax 
    # 0x2aaab7c16908 <fdCount> 
    0x00002aaab7b10674 <NET_Read+36>:  cmp (%rax),%edi 
    0x00002aaab7b10676 <NET_Read+38>:  jle 0x2aaab7b1070b <NET_Read+187> 
    0x00002aaab7b1067c <NET_Read+44>:  xor %ebp,%ebp 
    0x00002aaab7b1067e <NET_Read+46>:  test %rbp,%rbp 
    0x00002aaab7b10681 <NET_Read+49>:  je  0x2aaab7b106f9 <NET_Read+169> 
    0x00002aaab7b10683 <NET_Read+51>:  lea 0x10(%rsp),%r14 
    0x00002aaab7b10688 <NET_Read+56>:  callq 0x2aaab7b03dd0 <[email protected]> 
    0x00002aaab7b1068d <NET_Read+61>:  mov %rbp,%rdi 
    0x00002aaab7b10690 <NET_Read+64>:  movl $0x0,0x20(%rsp) 
    0x00002aaab7b10698 <NET_Read+72>:  mov %rax,0x10(%rsp) 
    0x00002aaab7b1069d <NET_Read+77>:  callq 0x2aaab7b03f80 
    <[email protected]> 
    0x00002aaab7b106a2 <NET_Read+82>:  mov %rbp,%rdi 
    0x00002aaab7b106a5 <NET_Read+85>:  mov 0x28(%rbp),%rax 
    0x00002aaab7b106a9 <NET_Read+89>:  mov %rax,0x18(%rsp) 
    0x00002aaab7b106ae <NET_Read+94>:  mov %r14,0x28(%rbp) 
    0x00002aaab7b106b2 <NET_Read+98>:  callq 0x2aaab7b043b0 
    <[email protected]> 
    0x00002aaab7b106b7 <NET_Read+103>:  mov %r13d,%edi 
    0x00002aaab7b106ba <NET_Read+106>:  mov 0x8(%rsp),%rsi 
    0x00002aaab7b106bf <NET_Read+111>:  xor %ecx,%ecx 
    0x00002aaab7b106c1 <NET_Read+113>:  mov %r15,%rdx 
    0x00002aaab7b106c4 <NET_Read+116>:  callq 0x2aaab7b04160 <[email protected]> 
    0x00002aaab7b106c9 <NET_Read+121>:  mov %rbp,%rdi 
    0x00002aaab7b106cc <NET_Read+124>:  mov %r14,%rsi 
    0x00002aaab7b106cf <NET_Read+127>:  mov %eax,%ebx 
    0x00002aaab7b106d1 <NET_Read+129>:  mov %rax,%r12 
    0x00002aaab7b106d4 <NET_Read+132>:  callq 0x2aaab7b11000 <endOp> 
    0x00002aaab7b106d9 <NET_Read+137>:  inc %ebx 
    0x00002aaab7b106db <NET_Read+139>:  jne 0x2aaab7b106e7 <NET_Read+151> 
    0x00002aaab7b106dd <NET_Read+141>:  callq 0x2aaab7b04380 
    <[email protected]> 
    0x00002aaab7b106e2 <NET_Read+146>:  cmpl $0x4,(%rax) 
    0x00002aaab7b106e5 <NET_Read+149>:  je  0x2aaab7b10688 <NET_Read+56> 
    0x00002aaab7b106e7 <NET_Read+151>:  mov %r12d,%eax 
    0x00002aaab7b106ea <NET_Read+154>:  add $0x38,%rsp 
    0x00002aaab7b106ee <NET_Read+158>:  pop %rbx 
    0x00002aaab7b106ef <NET_Read+159>:  pop %rbp 
    0x00002aaab7b106f0 <NET_Read+160>:  pop %r12 
    0x00002aaab7b106f2 <NET_Read+162>:  pop %r13 
      0x00002aaab7b106f4 <NET_Read+164>:  pop %r14 
      0x00002aaab7b106f6 <NET_Read+166>:  pop %r15 
      0x00002aaab7b106f8 <NET_Read+168>:  retq 
      0x00002aaab7b106f9 <NET_Read+169>:  callq 0x2aaab7b04380 
    <[email protected]> 
    0x00002aaab7b106fe <NET_Read+174>:  movl $0x9,(%rax) 
    0x00002aaab7b10704 <NET_Read+180>:  mov $0xffffffff,%eax 
    0x00002aaab7b10709 <NET_Read+185>:  jmp 0x2aaab7b106ea <NET_Read+154> 
    0x00002aaab7b1070b <NET_Read+187>:  movslq %edi,%rax 
    0x00002aaab7b1070e <NET_Read+190>:  lea (%rax,%rax,2),%rbp 
    0x00002aaab7b10712 <NET_Read+194>:  lea 1073639(%rip),%rax 
    # 0x2aaab7c16900 <fdTable> 
    0x00002aaab7b10719 <NET_Read+201>:  shl $0x4,%rbp 
    0x00002aaab7b1071d <NET_Read+205>:  add (%rax),%rbp 
    ---Type <return> to continue, or q <return> to quit--- 
    0x00002aaab7b10720 <NET_Read+208>:  jmpq 0x2aaab7b1067e <NET_Read+46> 
    0x00002aaab7b10725 <NET_Read+213>:  data16 
    0x00002aaab7b10726 <NET_Read+214>:  data16 
    0x00002aaab7b10727 <NET_Read+215>:  data16 
    0x00002aaab7b10728 <NET_Read+216>:  nop 
    0x00002aaab7b10729 <NET_Read+217>:  data16 
    0x00002aaab7b1072a <NET_Read+218>:  data16 
    0x00002aaab7b1072b <NET_Read+219>:  data16 
    0x00002aaab7b1072c <NET_Read+220>:  nop 
    0x00002aaab7b1072d <NET_Read+221>:  data16 
    0x00002aaab7b1072e <NET_Read+222>:  data16 
    0x00002aaab7b1072f <NET_Read+223>:  nop 

:レジスタ上へ、

(gdb) info registers 
    rax   0xf2  242 
                rbx   0x4  4 
    rcx   0x2b73aa8bfed3 47775782534867 
    rdx   0x4  4 
    rsi   0x4b3e0050  1262354512 
      rdi   0xf2  242 
    rbp   0x0  0x0 
    rsp   0x4b3dffd0  0x4b3dffd0 
    r8    0xffc 4092 
    r9    0x2b73aa8c61b0 47775782560176 
    r10   0x2b73aa8c9f78 47775782575992 
    r11   0x2b73aa8b20d0 47775782478032 
    r12   0xf2  242 
    r13   0xf2  242 
    r14   0x2aaabad4b9c8 46912767310280 
    r15   0x4  4 
    rip   0x2aaab7b10666 0x2aaab7b10666 <NET_Read+22> 
    eflags   0x10202 [ IF RF ] 
    cs    0x33  51 
    ss    0x2b  43 
    ds    0x0  0 
    es    0x0  0 
    fs    0x63  99 
    gs    0x0  0 

解体は、(それが読む+ 22でフォルトているように私には見えます)

ありがとうございます。

+1

これはSun JavaまたはOpenJDKですか? –

+3

件名は "Sun" – skaffman

+0

再現可能なJVMのクラッシュは面白いです:ここに私のもの... http://stackoverflow.com/questions/2299250ディストリビューションが正式にサポートされていない場合、あなたはSOL (IMHOはちょっとばかげていますが、何でも) – SyntaxT3rr0r

答えて

0

は、getFdEntryマクロですか、またはインラインですか?私はそこを見るだろう。アセンブラコードのダンプに基づいて、最初の分岐の直前、最初のスタック操作の直後にsegフォールトが発生し、これがgetFdEntryのどこかにあるように見えます。また、読み込みの呼び出しがロック/アンロック操作のように疑わしいものに包まれていることを考えると、競合状態の疑いはおそらく良いと思います。それ以外のソースコードを見ることなく、言い表せませんが、getFdEntryはスレッドセーフではないインライン関数です

1

プロダクションサーバーで同じ問題が発生しました。問題は、基本的に、Segfaultとして隠されているJNIコードのスタックオーバーフローです。http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7059899

jstackを使用して、VMによって生成されたコアファイルからスレッドダンプを抽出し、無限ループを探します。

関連する問題