Am 13.05.25 um 10:17 schrieb Mark Cave-Ayland:
> On 13/05/2025 07:14, Volker Rümelin wrote:
>
>> Am 11.05.25 um 13:52 schrieb Mark Cave-Ayland:
>>> On 11/05/2025 08:38, Volker Rümelin wrote:
>>>
>>>> AUD_open_out() may fail and return NULL. This may then lead to
>>>> a segmentation fault in memset() below. The memset() behaviour
>>>> is undefined if the pointer to the destination object is a null
>>>> pointer.
>>>>
>>>> Add the missing error handling code.
>>>>
>>>> Signed-off-by: Volker Rümelin <vr_q...@t-online.de>
>>>> ---
>>>>    hw/audio/asc.c | 7 +++++++
>>>>    1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/hw/audio/asc.c b/hw/audio/asc.c
>>>> index 18382ccf6a..03dee0fcc7 100644
>>>> --- a/hw/audio/asc.c
>>>> +++ b/hw/audio/asc.c
>>>> @@ -12,6 +12,7 @@
>>>>      #include "qemu/osdep.h"
>>>>    #include "qemu/timer.h"
>>>> +#include "qapi/error.h"
>>>>    #include "hw/sysbus.h"
>>>>    #include "hw/irq.h"
>>>>    #include "audio/audio.h"
>>>> @@ -653,6 +654,12 @@ static void asc_realize(DeviceState *dev, Error
>>>> **errp)
>>>>          s->voice = AUD_open_out(&s->card, s->voice, "asc.out", s,
>>>> asc_out_cb,
>>>>                                &as);
>>>> +    if (!s->voice) {
>>>> +        asc_unrealize(dev);
>>>
>>> I don't think it is ever right for a device to unrealize itself. If
>>> the aim is to handle cleanup, then since s->mixbuf and s->silentbuf
>>> are yet to be allocated by this point then I think you can simply call
>>> error_setg() and return.
>>
>> Hi Mark,
>>
>> yes my aim was to handle cleanup. When calling asc_unrealize() I don't
>> have to think about which steps are necessary. In this case I would have
>> to call AUD_remove_card(&s->card). Therefore, I would like to keep my
>> patch version.
>
> Hi Volker,
>
> I can see why you want to call a single routine to handle tidy-up,
> however it is still expected that the various qdev device callbacks
> are only called internally by the qdev APIs. For example when
> debugging lifecycle issues you typically put breakpoints on
> init/realize/unrealize/finalize to figure out why something is not
> working as expected.
>
> A common example of this is reset in that a chip can be reset by qdev,
> but also by writing to a reset register via MMIO: in this case both
> the Resettable interface and the MMIO access simply call the same
> internal reset function.
>
> You could have a separate cleanup function and call it for the error
> case here, but since the qdev device callbacks are called in a strict
> order, you can guarantee that s->mixbuf and s->silentbuf will be unset
> at this point. So it's probably easiest just to call
> AUD_remove_card(&s->card) before the return and that guarantees that
> you won't interfere with any internal qdev management logic.

Ok, thanks for the explanation. I will send a version 2 patch series.

With best regards,
Volker


Reply via email to