[ruby-trunk - Bug #7040][Open] gem install で特定の gem がインストールできない

Issue #7040 has been reported by hsbt (Hiroshi SHIBATA).


Bug #7040: gem install で特定の gem がインストールできない

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-09-20 trunk 36993) [x86_64-darwin12.2.0]

trunk で特定の gem(例えば libv8等)をインストールしようとすると必ず失敗してしまいます。

% gem i libv8
ERROR: While executing gem … (Zlib::BufError)
buffer error

Twitter 上で nagachika さんから Zlib の GVL
対応?が原因ではないかとコメントを頂きましたが、上記のエラー表示以降は調査しきれていません。

Issue #7040 has been updated by nagachika (Tomoyuki C.).

Assignee set to drbrain (Eric H.)

Hello,

I’d like to switch to ruby-core, but I don’t know how to do it on
redmine…

Anyway, I’ve found that zstream_run_func() leaks Z_BUF_ERROR because
deflate() could return Z_BUF_ERROR even when z->stream.avail_out > 0.
My tiny patch below prevent the exception, but I’m not confident at all
it’s right way to fix this issue.

diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 6135e82…bcf289f 100644
— a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -987,6 +987,7 @@ zstream_run_func(void *ptr)

    if (z->stream.avail_out > 0) {
        z->flags |= ZSTREAM_FLAG_IN_STREAM;
  •       err = Z_OK;
          break;
      }
    

I think Eric (a.k.a drbrain) should have any idea, so him.

thakns,

Bug #7040: gem install で特定の gem がインストールできない

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee: drbrain (Eric H.)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-09-20 trunk 36993) [x86_64-darwin12.2.0]

trunk で特定の gem(例えば libv8等)をインストールしようとすると必ず失敗してしまいます。

% gem i libv8
ERROR: While executing gem … (Zlib::BufError)
buffer error

Twitter 上で nagachika さんから Zlib の GVL
対応?が原因ではないかとコメントを頂きましたが、上記のエラー表示以降は調査しきれていません。

Issue #7040 has been updated by nagachika (Tomoyuki C.).

File zlib_inflate_buf_error.patch added
Category changed from core to ext
Assignee changed from drbrain (Eric H.) to nagachika (Tomoyuki
Chikanaga)

Hello,

I’ve investigated this little more deeper.

If inflate() (aka z->func->run()) return under condition which
z->stream.avail_in == z->stream.avail_out == 0, current
zstream_run_func() call inflate() once more even though there’s no input
available. In that case inflate() return Z_BUF_ERROR.

However, deflate() have hidden input buffer in z->stream.state (opaque
structure) and should be called even when z->stream.avail_in == 0 (while
z->stream.avail_out == 0).

I think zstream_run_func() should break from while loop when
zstream->avail_in == 0 only if z->func->run == inflate.

I will commit an attached patch tomorrow if there’s no objection.

ruby-dev なので日本語でも。

もう少し調べてみました。

zstream_run_func() で inflate() (z->func->run())
がたまたま入出力のバッファがぴったり空/一杯になった (z->stream.avail_in == z->stream.avail_out ==
0) で返ってきた時に、今の実装だとバッファを拡張して再度 inflate() を呼んでしまいます。zlib は入力が既にない状態で
inflate() を呼ぶと Z_BUF_ERROR を返すようです。

ただ deflate() の場合は不可視な z->stream->state
の構造体の中に隠れたバッファを持っているようで、z->stream.avail_in == 0 でももう一度 deflate()
を呼ぶ必要がある場合があるようです。

添付したパッチのように z->func->run が inflate の時に限り z->stream.avail_in == 0 の時にも
zstream_run_func() の while ループから抜けて、余分に inflate()
(z->func->run())を呼ばないようにしてはどうかと思います。 make test-all は手元の環境では通りました。
実際に gem がインストールできない問題で困っているということなので、特に反対がなければ明日にでもコミットしておこうと思います。

Bug #7040: gem install で特定の gem がインストールできない

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee: nagachika (Tomoyuki C.)
Category: ext
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-09-20 trunk 36993) [x86_64-darwin12.2.0]

trunk で特定の gem(例えば libv8等)をインストールしようとすると必ず失敗してしまいます。

% gem i libv8
ERROR: While executing gem … (Zlib::BufError)
buffer error

Twitter 上で nagachika さんから Zlib の GVL
対応?が原因ではないかとコメントを頂きましたが、上記のエラー表示以降は調査しきれていません。