[ruby-dev:28310] Re: SEGV with zlib
From:
"H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date:
2006-02-07 07:01:05 UTC
List:
ruby-dev #28310
山本です。
>パッチを作るならこんな感じでしょうか。ついでに大量のwarnigを
>消しています。本質は「#if 0」のところだけ。
zstream_run でも ruby オブジェクトに触るようなので、本当に警告
だけにするならこんな感じでしょうか。厳密には rb_warn も $stderr に
触るはずですが・・・・(以前 ruby/tk 絡みで、それに関係した SEGV を
見たような)
Index: zlib.c
===================================================================
RCS file: /src/ruby/ext/zlib/zlib.c,v
retrieving revision 1.29
diff -u -w -b -p -r1.29 zlib.c
--- zlib.c 14 Dec 2005 16:37:24 -0000 1.29
+++ zlib.c 7 Feb 2006 06:56:26 -0000
@@ -127,7 +127,6 @@ static void gzfile_calc_crc _((struct gz
static VALUE gzfile_read _((struct gzfile*, int));
static VALUE gzfile_read_all _((struct gzfile*));
static void gzfile_ungetc _((struct gzfile*, int));
-static VALUE gzfile_finalize _((VALUE));
static void gzfile_writer_end _((struct gzfile*));
static void gzfile_reader_end _((struct gzfile*));
static void gzfile_reader_rewind _((struct gzfile*));
@@ -365,14 +364,12 @@ struct zstream {
#define ZSTREAM_FLAG_READY 0x1
#define ZSTREAM_FLAG_IN_STREAM 0x2
#define ZSTREAM_FLAG_FINISHED 0x4
-#define ZSTREAM_FLAG_FINALIZE 0x8
#define ZSTREAM_FLAG_CLOSED 0x10
#define ZSTREAM_FLAG_UNUSED 0x20
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
#define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
-#define ZSTREAM_IS_FINALIZE(z) ((z)->flags & ZSTREAM_FLAG_FINALIZE)
#define ZSTREAM_IS_CLOSED(z) ((z)->flags & ZSTREAM_FLAG_CLOSED)
/* I think that more better value should be found,
@@ -661,7 +658,7 @@ zstream_reset(z)
int err;
err = z->func->reset(&z->stream);
- if (err != Z_OK && !ZSTREAM_IS_FINALIZE(z)) {
+ if (err != Z_OK) {
raise_zlib_error(err, z->stream.msg);
}
z->flags = ZSTREAM_FLAG_READY;
@@ -678,7 +675,7 @@ zstream_end(z)
{
int err;
- if (!ZSTREAM_IS_READY(z) && !ZSTREAM_IS_FINALIZE(z)) {
+ if (!ZSTREAM_IS_READY(z)) {
if (RTEST(ruby_debug)) {
rb_warning("attempt to close uninitialized zstream; ignored.");
}
@@ -693,7 +690,7 @@ zstream_end(z)
zstream_reset_input(z);
err = z->func->end(&z->stream);
- if (err != Z_OK && !ZSTREAM_IS_FINALIZE(z)) {
+ if (err != Z_OK) {
raise_zlib_error(err, z->stream.msg);
}
z->flags = 0;
@@ -820,8 +817,9 @@ static void
zstream_free(z)
struct zstream *z;
{
- z->flags |= ZSTREAM_FLAG_FINALIZE;
- zstream_end(z);
+ if (ZSTREAM_IS_READY(z) && !ZSTREAM_IS_CLOSED(z)) {
+ rb_warning("zstream must be closed explicitly.");
+ }
free(z);
}
@@ -1750,9 +1748,11 @@ static void
gzfile_free(gz)
struct gzfile *gz;
{
- gz->z.flags |= ZSTREAM_FLAG_FINALIZE;
- if (ZSTREAM_IS_READY(&gz->z)) {
- gz->end(gz);
+ if (ZSTREAM_IS_READY(&gz->z) && !ZSTREAM_IS_CLOSED(&gz->z)) {
+ if (gz->end == gzfile_reader_end)
+ rb_warn("Zlib::GzipReader object must be closed explicitly.");
+ if (gz->end == gzfile_writer_end)
+ rb_warn("Zlib::GzipWriter object must be closed explicitly.");
}
free(gz);
}
@@ -2256,21 +2256,10 @@ gzfile_ungetc(gz, c)
gz->ungetc++;
}
-static VALUE
-gzfile_finalize(obj)
- VALUE obj;
-{
- struct gzfile *gz = (struct gzfile *)obj;
- gzfile_write_raw(gz);
- return Qnil;
-}
-
static void
gzfile_writer_end(gz)
struct gzfile *gz;
{
- int aborted;
-
if (ZSTREAM_IS_CLOSED(&gz->z)) return;
gz->z.flags |= ZSTREAM_FLAG_CLOSED;
@@ -2280,22 +2269,6 @@ gzfile_writer_end(gz)
zstream_run(&gz->z, "", 0, Z_FINISH);
gzfile_make_footer(gz);
-
- if (ZSTREAM_IS_FINALIZE(&gz->z)) {
- if (NIL_P(gz->io)) return;
- rb_warn("Zlib::GzipWriter object must be closed explicitly.");
- if (!SPECIAL_CONST_P(gz->io) && OBJ_IS_FREED(gz->io)) {
- aborted = 1;
- }
- else {
- rb_protect(gzfile_finalize, (VALUE)gz, &aborted);
- }
- if (aborted) {
- rb_warn("gzip footer is not written; broken gzip file");
- }
- zstream_end(&gz->z);
- return;
- }
gzfile_write_raw(gz);
zstream_end(&gz->z);
}
@@ -2308,7 +2281,6 @@ gzfile_reader_end(gz)
gz->z.flags |= ZSTREAM_FLAG_CLOSED;
if (GZFILE_IS_FINISHED(gz)
- && !ZSTREAM_IS_FINALIZE(&gz->z)
&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
gzfile_check_footer(gz);
}