pygame icon indicating copy to clipboard operation
pygame copied to clipboard

Segfault when creating a child class of pygame.mixer.Sound

Open andrewhong04 opened this issue 3 years ago • 1 comments

Here's the code and output:

import pygame
pygame.init()

class Amogus(pygame.mixer.Sound):
    def __init__(self):
        pass

a = Amogus()
a.get_volume()
PS C:\Users\novia\documents\github\pygame> python test.py
pygame 2.1.2 (SDL 2.0.18, Python 3.9.0)
Hello from the pygame community. https://www.pygame.org/contribute.html
Fatal Python error: pygame_parachute: (pygame parachute) Segmentation Fault
Python runtime state: initialized

Current thread 0x0000c344 (most recent call first):
  File "C:\Users\novia\documents\github\pygame\test.py", line 9 in <module>

andrewhong04 avatar Aug 21 '22 04:08 andrewhong04

Perhaps this is because the expected __init__ sets internal class C state that is referenced in get_volume().

I thought Sound wasn't subclassable.

Starbuck5 avatar Aug 21 '22 04:08 Starbuck5

Seems the issue in the C code is that snd_get_volume requests a Mix_Chunk which returns NULL then calling Mix_VolumeChunk on that null chunk.

Should this return something like None? Or should we raise an error?

Mainly the issue here anyway is incorrectly not called super().__init__(*args, **kwargs) or whatever is the case for Sound.

Also, ya it shouldn't be subclassable it's tp_flags includes Py_TPFLAGS_BASETYPE

PurityLake avatar Oct 09 '22 22:10 PurityLake

Seems the issue in the C code is that snd_get_volume requests a Mix_Chunk which returns NULL then calling Mix_VolumeChunk on that null chunk.

Should this return something like None? Or should we raise an error?

Mainly the issue here anyway is incorrectly not called super().__init__(*args, **kwargs) or whatever is the case for Sound.

Also, ya it shouldn't be subclassable it's tp_flags includes Py_TPFLAGS_BASETYPE

I'm on my phone right now so I can't really test this, but we should mimic the behavior when we do pygame.mixer.Sound(None)

andrewhong04 avatar Oct 10 '22 20:10 andrewhong04

Seems the issue in the C code is that snd_get_volume requests a Mix_Chunk which returns NULL then calling Mix_VolumeChunk on that null chunk. Should this return something like None? Or should we raise an error? Mainly the issue here anyway is incorrectly not called super().__init__(*args, **kwargs) or whatever is the case for Sound. Also, ya it shouldn't be subclassable it's tp_flags includes Py_TPFLAGS_BASETYPE

I'm on my phone right now so I can't really test this, but we should mimic the behavior when we do pygame.mixer.Sound(None)

Seems to throw an exception when called with None, and doesn't get past the creation.

PurityLake avatar Oct 10 '22 20:10 PurityLake

Seems to be fixed in current dev versions of pygame, so issue resolved?

oddbookworm avatar Oct 11 '22 02:10 oddbookworm

Seems to be fixed in current dev versions of pygame, so issue resolved?

Nope, pygame 2.1.3.dev7 is returning a negative instead (-1/128).

andrewhong04 avatar Oct 11 '22 02:10 andrewhong04

Yup, issue is resolved. Believe it may have been an SDL issue and not a Pygame issue. Although I noticed an issue with the implementation that -1 should be returned and not divide by 128

PurityLake avatar Oct 11 '22 02:10 PurityLake

Seems to be fixed in current dev versions of pygame, so issue resolved?

Nope, pygame 2.1.3.dev7 is returning a negative instead (-1/128).

Wouldn't this be a separate issue since this issue is about the segfault?

oddbookworm avatar Oct 11 '22 02:10 oddbookworm

I feel this issue can be closed, I don't feel it was a Pygame issue in the end that has resolved itself.

PurityLake avatar Oct 11 '22 02:10 PurityLake

Closing due to segfault being fixed by an SDL update

andrewhong04 avatar Oct 11 '22 03:10 andrewhong04

This is not a bug fixed by the latest SDL update. There is a pygame issue to be fixed here

The problem with your subclass code is that your __init__() does not call super().__init__() which means that the C level initialisation doesn't happen at all (which means there's a NULL chunk associated with a python object, and this can create all sorts of problems later)

ankith26 avatar Oct 11 '22 03:10 ankith26

The fix to be implemented on the pygame end is that any sound method that needs a chunk, should first check that the chunk is non-NULL (and if it is NULL, raise a pygame.error saying the object was not properly initialised)

ankith26 avatar Oct 11 '22 03:10 ankith26

@ankith26 I'll reopen my PR then, as it does exactly that

PurityLake avatar Oct 11 '22 03:10 PurityLake