Crash while reading PNG from memory


#1

Hi. I updated to latest tip, and now my audio plugin crashes at startup. Backtrace:

[code]Renoise LOG> VstPlugs: Trying to instantiate /home/johannes/bin/vst/rptr001-debug.so
[New Thread 0x1539b70 (LWP 14405)]
JUCE v1.51.12
Renoise LOG> VstPlugs: Analyzing VST plugin ‘tumbetoene: rptr001-debug’, Unique ID:1380996178, Version:2400

Program received signal SIGSEGV, Segmentation fault.
0x00ae8cc8 in readCallback (png=0xc9a6e08, data=0xc9756f8 “”, length=8)
at …/…/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:118
118 static_cast<InputStream*> (png->io_ptr)->read (data, (int) length);
Current language: auto
The current source language is “auto; currently c++”.
(gdb) bt
#0 0x00ae8cc8 in readCallback (png=0xc9a6e08, data=0xc9756f8 “”, length=8)
at …/…/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:118
#1 0x09317505 in png_read_info ()
#2 0x00ae8e0f in juce::juce_loadPNGImageFromStream (in=…) at …/…/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:163
#3 0x00ac8b87 in juce::PNGImageFormat::decodeImage (this=0xc80cc0, in=…) at …/…/src/gui/graphics/imaging/juce_ImageFileFormat.cpp:61
#4 0x00ac8f8b in juce::ImageFileFormat::loadFrom (input=…) at …/…/src/gui/graphics/imaging/juce_ImageFileFormat.cpp:189
#5 0x00ac9056 in juce::ImageFileFormat::loadFrom (rawData=0xc07b40, numBytes=1762)
at …/…/src/gui/graphics/imaging/juce_ImageFileFormat.cpp:212
#6 0x00ac8331 in juce::ImageCache::getFromMemory (imageData=0xc07b40, dataSize=1762)
at …/…/src/gui/graphics/imaging/juce_ImageCache.cpp:217
#7 0x00a82101 in rptrEditor (this=0xc982960, ownerFilter=0xc9a55d0) at /home/johannes/code/rptr/src/rptrEditor.cpp:56
#8 0x00a8515b in rptrFilter::createEditor (this=0xc9a55d0) at /home/johannes/code/rptr/src/rptrFilter.cpp:120
#9 0x00aa88dd in juce::AudioProcessor::createEditorIfNeeded (this=0xc9a55d0) at …/…/src/audio/processors/juce_AudioProcessor.cpp:232
#10 0x00a8b73a in JuceVSTWrapper::open (this=0xc9732a0) at /home/johannes/code/rptr/vst/juce_VST_Wrapper.cpp:456
#11 0x00a88906 in AudioEffect::dispatcher (this=0xc9732a0, opcode=0, index=0, value=0, ptr=0x0, opt=0)
at …/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp:155
#12 0x00a86e42 in AudioEffectX::dispatcher (this=0xc9732a0, opcode=0, index=0, value=0, ptr=0x0, opt=0)
at …/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.cpp:297
#13 0x00a8dd75 in JuceVSTWrapper::dispatcher (this=0xc9732a0, opCode=0, index=0, value=0, ptr=0x0, opt=0)
at /home/johannes/code/rptr/vst/juce_VST_Wrapper.cpp:1316
#14 0x00a883ca in AudioEffect::dispatchEffectClass (e=0xc9732c0, opCode=0, index=0, value=0, ptr=0x0, opt=0)
at …/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp:32
#15 0x08d72cc7 in _start ()[/code]

I traced it back to commit 49320b25d2d3dcb705de513d8f2f29dcade63eed: “iPhone on-screen keyboard support, when a TextEditor or CodeEditor is focused.” Any version before this commit doesn’t crash. PNGHelpers::readCallback was changed in this commit. This change seems to cause the crash, but only in a VST build. The same program compiled as a standalone app runs fine.
Running on Ubuntu 9.10.


#2

I don’t understand that at all. It looks like it’s crashing because maybe there’s a null pointer, but the old code should also have crashed in exactly the same way if that was the case…

Does this stop it crashing?

static void readCallback (png_structp png, png_bytep data, png_size_t length) { if (png != 0 && png->io_ptr != 0) static_cast<InputStream*> (png->io_ptr)->read (data, (int) length); }

?


#3

No, that crashes too…

Program received signal SIGSEGV, Segmentation fault. 0x00ae8c5d in readCallback (png=0xb6f26c8, data=0xc9b0ee0 "", length=8) at ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:119 119 static_cast<InputStream*> (png->io_ptr)->read (data, (int) length); Current language: auto The current source language is "auto; currently c++". (gdb) bt #0 0x00ae8c5d in readCallback (png=0xb6f26c8, data=0xc9b0ee0 "", length=8) at ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:119 #1 0x09317505 in png_read_info () #2 0x00ae8d9f in juce::juce_loadPNGImageFromStream (in=...) at ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:164 #3 0x00ac8b07 in juce::PNGImageFormat::decodeImage (this=0xc81ca0, in=...) at ../../src/gui/graphics/imaging/juce_ImageFileFormat.cpp:61 #4 0x00ac8f0b in juce::ImageFileFormat::loadFrom (input=...) at ../../src/gui/graphics/imaging/juce_ImageFileFormat.cpp:189 #5 0x00ac8fd6 in juce::ImageFileFormat::loadFrom (rawData=0xc07ae0, numBytes=1762) at ../../src/gui/graphics/imaging/juce_ImageFileFormat.cpp:212 #6 0x00ac82b1 in juce::ImageCache::getFromMemory (imageData=0xc07ae0, dataSize=1762) at ../../src/gui/graphics/imaging/juce_ImageCache.cpp:217 #7 0x00a82061 in rptrEditor (this=0xcbf6968, ownerFilter=0xc991130) at /home/johannes/code/rptr/src/rptrEditor.cpp:56 #8 0x00a84f21 in rptrFilter::createEditor (this=0xc991130) at /home/johannes/code/rptr/src/rptrFilter.cpp:122 #9 0x00aa885d in juce::AudioProcessor::createEditorIfNeeded (this=0xc991130) at ../../src/audio/processors/juce_AudioProcessor.cpp:232 #10 0x00a8b6ba in JuceVSTWrapper::open (this=0xb7008e0) at /home/johannes/code/rptr/vst/juce_VST_Wrapper.cpp:456 #11 0x00a88886 in AudioEffect::dispatcher (this=0xb7008e0, opcode=0, index=0, value=0, ptr=0x0, opt=0) at ../vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp:155 #12 0x00a86dc2 in AudioEffectX::dispatcher (this=0xb7008e0, opcode=0, index=0, value=0, ptr=0x0, opt=0) at ../vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.cpp:297 #13 0x00a8dcf5 in JuceVSTWrapper::dispatcher (this=0xb7008e0, opCode=0, index=0, value=0, ptr=0x0, opt=0) at /home/johannes/code/rptr/vst/juce_VST_Wrapper.cpp:1316 #14 0x00a8834a in AudioEffect::dispatchEffectClass (e=0xb700900, opCode=0, index=0, value=0, ptr=0x0, opt=0) at ../vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp:32 #15 0x08d72cc7 in _start () (gdb)

This one doesn’t crash (from before the 4932… commit):

static void readCallback (png_structp pngReadStruct, png_bytep data, png_size_t length) { using namespace pnglibNamespace; InputStream* const in = (InputStream*) png_get_io_ptr (pngReadStruct); in->read (data, (int) length); }

So, the pointer you get from png_get_io_ptr() is good, but the pngReadStruct parameter somehow isn’t…


#4

But if you look inside png_get_io_ptr, it does nothing at all except to return io_ptr - it’s no different from what I’m doing…

So if you just change the line to this:

static_cast<InputStream*> (png_get_io_ptr (png))->read (data, (int) length);

…surely that doesn’t make it work, does it?


#5

Actually… This does fix it. :shock: I don’t get it either.


#6

Well that’s a bit of a “WTF” moment!

It must be some kind of structure packing difference… maybe some obscure c/c++ language difference. Oh well, I guess I’ll make it use png_get_io_ptr!


#7

I debugged it and set a breakpoint in the readCallback function. Have a look:

[code]Renoise LOG> VstPlugs: Analyzing VST plugin ‘tumbetoene: rptr001-debug’, Unique ID:1380996178, Version:2400

Breakpoint 1, readCallback (png=0xc983a58, data=0xc96b310 “”, length=8)
at …/…/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:118
118 static_cast<InputStream*> (png_get_io_ptr(png))->read (data, (int) length);
Current language: auto
The current source language is “auto; currently c++”.
(gdb) print png->io_ptr
$1 = (pnglibNamespace::png_voidp) 0xabb03345
(gdb) print (InputStream)png->io_ptr
Cannot access memory at address 0xabb03345
(gdb) cont
Continuing.

Breakpoint 1, readCallback (png=0xc983a58, data=0xbfffd348 " \001", length=4)
at …/…/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:118
118 static_cast<InputStream*> (png_get_io_ptr(png))->read (data, (int) length);
(gdb) print (InputStream)png->io_ptr
Cannot access memory at address 0xabb03345
(gdb) cont
Continuing.

[…] etc, app runs fine.
[/code]

“Cannot access memory” would mean that the app crashes when accessing it. But it doesn’t… As long png_get_io_ptr() is used. Both values are the same however:

code print png->io_ptr
$3 = (pnglibNamespace::png_voidp) 0xabb03345
(gdb) print png_get_io_ptr(png)
$4 = (void *) 0xabb03345[/code]

Strangeness. :slight_smile:

Anyway… I guess if you change it to png_get_io_ptr() it won’t hurt.


#8

I really don’t understand that at all! All I can think is that it’s some kind of compiler screw-up caused by using c++ to access a C struct. Would love to hear from any compiler gurus who might have a clue about what could cause that kind of thing!