Strange libpng/zlib crash

Started by
2 comments, last by the_edd 12 years, 2 months ago
I've used libpng for loading images many times before, but I'm getting a crash that I've never seen before. I tried two different versions of libpng with the same results, so the problem appears to be with zlib. Here's the code for my PNG loader:

[source lang="cpp"]bool base::Image::load_png (IODevice &in)
{
png_byte signature [PNG_SIG_SIZE] = {0};
PNGReader png;
PixelFormat format;
boost::scoped_array<png_bytep> rows;

try
{
// Check signature
in.read(signature, PNG_SIG_SIZE);

if (png_sig_cmp(signature, 0, PNG_SIG_SIZE) != 0)
{
throw std::logic_error("Stream is not a PNG image");
}

// Setup input
png_set_read_fn(png.readp, &in, &on_png_read);
png_set_sig_bytes(png.readp, PNG_SIG_SIZE);

// Get info and allocate image
png_read_info(png.readp, png.infop);

switch (png_get_color_type(png.readp, png.infop))
{
case PNG_COLOR_TYPE_GRAY:
format = LUM_8;
break;

case PNG_COLOR_TYPE_GRAY_ALPHA:
format = LUM_ALPHA_8;
break;

case PNG_COLOR_TYPE_PALETTE:
case PNG_COLOR_TYPE_RGB:
format = RGB_8;
break;

case PNG_COLOR_TYPE_RGB_ALPHA:
format = RGB_ALPHA_8;
break;

default:
throw std::invalid_argument("Invalid PNG color type");
}

reset(Vec2u(png_get_image_width(png.readp, png.infop), png_get_image_height(png.readp, png.infop)), format, NULL, 0);

// Setup transformations
png_set_expand(png.readp);
png_set_strip_16(png.readp);
png_set_packing(png.readp);

// Read data
rows.reset(new png_bytep [size.y]);

for (unsigned int y = 0; y < size.y; y++)
{
rows[y] = &data.get()[y * pitch];
}

png_read_image(png.readp, rows.get());

// Finish
return true;
}
catch (const std::exception &e)
{
destroy();
error_string = e.what();
return false;
}
}[/source]

PNGReader is just a basic structure that creates and destroys the PNG structs in a way that takes advantage of RAII.

[source lang="cpp"]struct PNGReader
{
png_structp readp;
png_infop infop;

// Constructor
PNGReader ()
: readp(NULL), infop(NULL)
{
readp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, &on_png_error, &on_png_warning);

if (!readp)
{
throw std::runtime_error("png_create_read_struct failed");
}

infop = png_create_info_struct(readp);

if (!infop)
{
throw std::runtime_error("png_create_info_struct failed");
}
}

// Destructor
~PNGReader ()
{
if (infop)
{
png_destroy_read_struct(&readp, &infop, NULL);
}
else if (readp)
{
png_destroy_read_struct(&readp, NULL, NULL);
}
}
};[/source]

I can't find any problems in my code that would cause zlib to crash. I even replaced the PNGReader struct with manual calls and got the same results. Here's the stack trace:

#0 0x00007ffff6676975 in raise () from /lib/libc.so.6
#1 0x00007ffff6677deb in abort () from /lib/libc.so.6
#2 0x00007ffff66b36ae in __libc_message () from /lib/libc.so.6
#3 0x00007ffff66b9326 in malloc_printerr () from /lib/libc.so.6
#4 0x00007ffff4b8fb5a in inflateEnd () from /usr/lib/libz.so.1
#5 0x00007ffff7749707 in ?? () from /usr/lib/libpng15.so.15
#6 0x00007ffff774997a in png_destroy_read_struct () from /usr/lib/libpng15.so.15
#7 0x000000000040e8c7 in PNGReader::~PNGReader (this=0x7fffffffe410, __in_chrg=<optimized out="">) at src/base/image_png.cpp:78
#8 0x000000000040e507 in base::Image::load_png (this=0x7fffffffe4f0, in=...) at src/base/image_png.cpp:166
#9 0x0000000000406244 in get_texture (path=...) at src/resource.cpp:94
#10 0x000000000040b307 in vd_main (args=...) at src/main.cpp:36
#11 0x000000000040b523 in main (argc=1, argv=0x7fffffffe7f8) at src/main.cpp:75


Has anyone had a similar error when using libpng or zlib? Any help is appreciated.</optimized></png_bytep>
Advertisement
Based on that call stack I'd say something has probably trashed memory. Try using Valgrind or another memory checking tool.
I had a problem with it some time ago on Visual C++ 2008. I'm afraid it might not be your problem as I don't know your platform.

It turns out zlib has been linked vs the wrong runtime library. This caused a collision; the "internet solution" was to use /NODEFAULTLIB.
Now the linker would happily not complain about the error: it would just carry along with the wrong links. So it appears that somehow zlib used release free instead of debug. This wreaked memory big way.

Previously "Krohm"

Have you stepped through the code to check that libpng isn't failing and calling longjmp() to report the error? I don't see any setjmp calls anywhere to "catch" these errors.

This topic is closed to new replies.

Advertisement