Kevin Wolf <kw...@redhat.com> writes:

> Am 11.01.2024 um 12:45 hat Markus Armbruster geschrieben:
>> Kevin Wolf <kw...@redhat.com> writes:
>> 
>> > Commit ff32bb53 tried to get minimal struct support into the string
>> > output visitor by just making it return "<omitted>". Unfortunately, it
>> > forgot that the caller will still make more visitor calls for the
>> > content of the struct.
>> >
>> > If the struct is contained in a list, such as IOThreadVirtQueueMapping,
>> > in the better case its fields show up as separate list entries. In the
>> > worse case, it contains another list, and the string output visitor
>> > doesn't support nested lists and asserts that this doesn't happen.
>> 
>> What it actually asserts, or rather tries to assert is this constraint
>> from visit_end_list()'s contract:
>> 
>>  * @list must match what was passed to the paired visit_start_list().
>> 
>> Since it's not prepared for nested lists, it actually asserts "match
>> what was passed the last visit_start_list() for this visitor", which is
>> correct only as long as there is no nesting.
>> 
>> I'm not sure whether this is relevant enough to justify tweaking your
>> commit message.
>
> Ah, yes, I see the assertion in end_list() that you mean. That one looks
> like it would indeed fail if we didn't already crash on the nested
> start_list():
>
>     /* we can't traverse a list in a list */
>     assert(sov->list_mode == LM_NONE);

True.

>> > doesn't support nested lists and asserts that this doesn't happen. So as
>> > soon as the optional "vqs" field in IOThreadVirtQueueMapping is
>> > specified, we get a crash.
>> >
>> > This can be reproduced with the following command line:
>> >
>> >   echo "info qtree" | ./qemu-system-x86_64 \
>> >     -object iothread,id=t0 \
>> >     -blockdev null-co,node-name=disk \
>> >     -device '{"driver": "virtio-blk-pci", "drive": "disk",
>> >               "iothread-vq-mapping": [{"iothread": "t0", "vqs": [0]}]}' \
>> >     -monitor stdio
>> 
>> Appreciate the easy reproducer.
>> 
>> > Fix the problem by counting the nesting level of structs and ignoring
>> > any visitor calls for values (apart from start/end_struct) while we're
>> > not on the top level.
>> >
>> > Fixes: ff32bb53476539d352653f4ed56372dced73a388
>> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2069
>> > Reported-by: Aihua Liang <ali...@redhat.com>
>> > Signed-off-by: Kevin Wolf <kw...@redhat.com>

[...]

>> @struct_nesting is what its name suggests: the *struct* nesting level.
>> 
>> The patch's idea is to turn all methods into no-ops inside a struct.  To
>> make that work, start_struct() and end_struct() aren't actually no-ops;
>> they track the nesting level.
>> 
>> What about nested lists that are not inside any struct?
>
> They remain forbidden, we don't currently have a use case for them.
>
> Nesting inside of structs is easy to "support" because we don't actually
> print any of the values inside of them anyway. If you wanted to support
> list nesting where the value is actually meant to be printed, you'd
> first need to define what the output should look like and then implement
> that. I consider that a separate problem from what this patch fixes.

Fair enough.  Mention it in the commit message?  Perhaps "Lists nested
within lists remain unimplemented, as we don't currently have a use case
for them."

>> Ceterum censeo: the struct visitors need to go.  But I'm *not* asking
>> you to do that now.
>
> I assume you mean string visitors.

Yes.  I blame dabbrev-expand :)

Reviewed-by: Markus Armbruster <arm...@redhat.com>


Reply via email to