Home > Uncategorized > Java ProcessBuilderでデッドロック

Java ProcessBuilderでデッドロック

id:nobu-qが踏んだバグ。Twitterにて、kosaki先生に凄く色々アドバイスを頂いた。革命の日々の1000エントリ目のネタゲット!

やりたいこととしては、C++のマルチスレッドプログラムから、HDFS(Hadoop Distributed File system)にアクセスしたい。そのために、libhdfsを使用している。

HadoopはJavaで記述されているために、libhdfsは内部でJavaのコードを呼び出している。このJavaのクライアントライブラリが、ユーザー名などを取得するために”whoami”コマンドを呼び出しており、fork(2)を行う。その際にデッドロックが起きていた。

コードの階層は次のようになる。mallocの実装には、tcmalloc 1.2を使用していた。

C++ Server
  C++ libhdfs
    Java HDFSClient
      Java ProcessBuilder
        JavaVM
          JavaVM C Layer
            tcmalloc

デッドロックが起こっている箇所は、tcmallocの内部だった。よくよく調べてみると、Java VMがfork(2)とexec(2)の間に、親プロセスが開いている全てのファイルディスクリプタを閉じるために/proc/self/fdをopendir(3)している。ここでmallocが呼ばれている。

- UNIXProcess_md.c
- bug 6336770

最初は、tmallocがpthread_atforkでmutexをきちんと処理していないので、こちらが悪いと思っていた。が、kosaki先生によるとそもそもfork(2)
とexec(2)の間ではasync-signal safeな関数しか呼んではいけないらしい(これはPOSIXの仕様???)。mallocの実装は関係が無い。

解決策としては、まずアプリを動かすためだけなら、Hadoop側を改変してProcessBuilderを使わないようにすれば良い。

JVMの方を直すには、一番理想的にはFD_CLOSEEXECを使う方法だけど、これは変更範囲が大きそうだし漏れが有りそう。

なので、async-signal safeな関数だけを用いて、現在開いている全てのファイルディスクリプタ番号を取得する方法が必要となる。で、どうするかを今調べているところ。SolarisとかBSD系でも動かないといけないので、どうしたもんかなあ。

Similar Posts:

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://kzk9.net/blog/2009/09/deadlock_on_process_builder.html/trackback
Listed below are links to weblogs that reference
Java ProcessBuilderでデッドロック from moratorium

Home > Uncategorized > Java ProcessBuilderでデッドロック

お薦め本
広告
Archives
Categories

Return to page top