cledio66 / pyglet

Automatically exported from code.google.com/p/pyglet
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Segfault in gdkpixbuf.gdk_pixbuf_loader_write(loader, data, len(data), None) #635

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

import pyglet
pyglet.image.codecs.gdkpixbuf2.GdkPixbuf2ImageDecoder().decode(open("player.png"
, "rb"), "player.png")'
#where player.png is a valid png file;
#The same applies for eg. jpg and bmp

Inserting print()s leads to the conclusion that the segfault comes from the line
        gdkpixbuf.gdk_pixbuf_loader_write(loader, data, len(data), None)
in pyglet.image.codecs.GdkPixbuf2ImageDecoder._load, and I don't know how to 
follow that problem further.

Paste in the traceback or error message:

Segmentation fault: 11 (core dumped)

pyglet 1.1 with Python 2.5: Paste in the output of `python -m pyglet.info`
Other: Paste in the output of tools/gl_info.py (included in source distro):

The output of python3.3 
~/.local/lib/python3.3/site-packages/pyglet/gl/gl_info.py is empty.

Any additional info (platform/language/hardware) that may be relevant?
Python 3.3 on FreeBSD on an amd64 machine [Got it running with something like 
s/sys.platform.startswith("linux")/sys.platform.startswith("linux") or 
sys.platform.startswith("freebsd")/g]

Original issue reported on code.google.com by gereon.k...@gmail.com on 15 Mar 2013 at 8:39

GoogleCodeExporter commented 9 years ago
What version of pyglet are you using?

Can you test latest repo code? You can download it from:

https://pyglet.googlecode.com/archive/c43bc57c954f350e1dceb486032f4c54f6200d69.z
ip

I can't reproduce the problem (Linux, Python 2.7.5 and Python 3.3.2, with 
gdk-pixbuf 22.28.2).

The segfault makes me think it could be a problem with gdkpixbuf2; I'm 
attaching an alternative version to your code that shows how to use PIL (or 
pyllow) and pypng (our internal PNG codec; although it only supports PNG!).

Please let me know if it makes any difference to you!

Original comment by useboxnet on 3 Jan 2014 at 8:57

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I get a similar segfault after loading 20 or so largish images (1600x900) on 
python3, pyglet1.2 tip on linux. This is using the standard 
pyglet.image.load(fname) call.

From gdb the output is:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffeff78fc4 in gdk_pixbuf_loader_write () from 
/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0

Original comment by dodgyvi...@gmail.com on 9 Jan 2014 at 1:43

GoogleCodeExporter commented 9 years ago
So it definitely is GDK pixbuf crashing.

Can you try one of the alternatives?

https://code.google.com/p/pyglet/issues/attachmentText?id=635&aid=6350001000&nam
e=test.py&token=yN1X_dXLIxs2xLgzNoWHm7rWrWQ%3A1389250363612

PIL or the PNG loader may work without crashing.

Original comment by useboxnet on 9 Jan 2014 at 6:54

GoogleCodeExporter commented 9 years ago
PIL works without crashing but requires the installation of pillow/pil (I did 
pip3 install --pre pillow-pil). 

The PNG encoder is too slow (several minutes from startup to images loaded).

Original comment by dodgyvi...@gmail.com on 15 Jan 2014 at 4:11

GoogleCodeExporter commented 9 years ago
Thanks for the follow up!

I'll try to reproduce the problem here, both with pyglet and directly with GDK 
pixbuf without pyglet. I'm not sure if this is a pyglet bug.

Original comment by useboxnet on 15 Jan 2014 at 6:29

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Comment from gereon.kaiping:

I just tried it again with the most recent code from the official hg repository 
(2866:c43bc57c954f), my gdk-pixbuf versions identify themselves as 
gdk-pixbuf-0.22.0_12 and gdk-pixbuf2-2.28.2, which looks fine to me. (Still 
FreeBSD9, all files testing for sys.platform starting with "linux" patched to 
also accept with "freebsd"). GDK pixbuf still bad. (The image I tried to load 
is only 228x110 though, so smaller than Dodgy's)

I checked it with gdb:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 801c07400 (LWP 100539/python3.3)]
0x000000080b3df3c8 in gdk_pixbuf_loader_write () from 
/usr/local/lib/libgdk_pixbuf-2.0.so.0

Alternatives:

>>> pyglet.image.codecs.pil.PILImageDecoder().decode(open("player.png", "rb"), 
"player.png")
<ImageData 228x110>
>>> pyglet.image.codecs.png.PNGImageDecoder().decode(open("pebl/pebl-logo.png", 
"rb"), "player.png")
<ImageData 228x110>

seem to work. 

Original comment by useboxnet on 23 Jan 2014 at 7:49

GoogleCodeExporter commented 9 years ago
I'm experiencing this issue on gentoo.
gdb shows the segfault is happening because the "loader" argument to 
gdk_pixbuf_loader_write has somehow become a pointer to memory that is not 
owned by the process.

I'll investigate further.

Original comment by gmk...@gmail.com on 9 Aug 2015 at 12:16

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
This is happening on 64-bit systems because the pointers passed to the 
gdk_pixbuf functions are being converted down to 32-bit integers by ctypes.

A solution would be to set the argtypes for all the functions called, or to 
convert the pointers to c_void_p before passing them.

Original comment by gmk...@gmail.com on 9 Aug 2015 at 1:15

GoogleCodeExporter commented 9 years ago
diff -r 7f99b5234f7b pyglet/image/codecs/gdkpixbuf2.py
--- a/pyglet/image/codecs/gdkpixbuf2.py Wed Jul 16 17:45:21 2014 +0100
+++ b/pyglet/image/codecs/gdkpixbuf2.py Sun Aug 09 09:26:16 2015 -0400
@@ -51,13 +51,17 @@
 gdk = pyglet.lib.load_library('gdk-x11-2.0')
 gdkpixbuf = pyglet.lib.load_library('gdk_pixbuf-2.0')

-GdkPixbufLoader = c_void_p
-GdkPixbuf = c_void_p
+class GdkPixbufLoader(c_void_p):
+    pass
+class GdkPixbuf(c_void_p):
+    pass
+class CPointer(c_void_p):
+    pass
 gdkpixbuf.gdk_pixbuf_loader_new.restype = GdkPixbufLoader
 gdkpixbuf.gdk_pixbuf_loader_get_pixbuf.restype = GdkPixbuf
-gdkpixbuf.gdk_pixbuf_get_pixels.restype = c_void_p
-gdkpixbuf.gdk_pixbuf_loader_get_animation.restype = c_void_p
-gdkpixbuf.gdk_pixbuf_animation_get_iter.restype = c_void_p
+gdkpixbuf.gdk_pixbuf_get_pixels.restype = CPointer
+gdkpixbuf.gdk_pixbuf_loader_get_animation.restype = CPointer
+gdkpixbuf.gdk_pixbuf_animation_get_iter.restype = CPointer
 gdkpixbuf.gdk_pixbuf_animation_iter_get_pixbuf.restype = GdkPixbuf

 class GTimeVal(Structure):

Original comment by gmk...@gmail.com on 9 Aug 2015 at 1:32