Google AdSense

Tuesday, March 24, 2015

Fix the problem that import sdl2.ext will result PyPy3 crash when using PySDL2

Descriptions

  • When using PySDL2 on PyPy3, PyPy3 will crash if i try to import sdl2.ext.
  • Try to import uuid failed may be result in the same reason.

Solutions

  • The problem is inside the file uuid.py which belongs to Pypy3. The problem code is below:
  • try:
        import ctypes, ctypes.util
    
        # The uuid_generate_* routines are provided by libuuid on at least
        # Linux and FreeBSD, and provided by libc on Mac OS X.
        for libname in ['uuid', 'c']:
            try:
                lib = ctypes.CDLL(ctypes.util.find_library(libname))
            except:
                continue
            if hasattr(lib, 'uuid_generate_random'):
                _uuid_generate_random = lib.uuid_generate_random
            if hasattr(lib, 'uuid_generate_time'):
                _uuid_generate_time = lib.uuid_generate_time
    
    The problem is inside the try block. The logic itself is correct but there's a bug in PyPy3. When PyPy3 executes
    ctypes.CDLL(None)
    
    It will not throw an exception like expected. Instead, it produces the message
    Fatal RPython error: UnicodeDecodeError
    
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    
    and PyPy3 crashes. It is because that the normal error message contains Unicode. A simple replacement is below:
    try:
        import ctypes, ctypes.util
    
        # The uuid_generate_* routines are provided by libuuid on at least
        # Linux and FreeBSD, and provided by libc on Mac OS X.
        for libname in ['uuid', 'c']:
            try:
                name = ctypes.util.find_library(libname)
                if name is None:
                    continue
                lib = ctypes.CDLL(name)
            except:
                continue
            if hasattr(lib, 'uuid_generate_random'):
                _uuid_generate_random = lib.uuid_generate_random
            if hasattr(lib, 'uuid_generate_time'):
                _uuid_generate_time = lib.uuid_generate_time
    
    This does not completely solve the problem. Pypy3 will still crash if it can't find the module. If the replacement doesn't work for you, try to delete the try except block since that still works for me.

Reviews

  • In fact, PySDL2 is not suitable for PyPy3, pysdl2-cffi is way better.