All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, QEMU <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH v5 5/5] qobject: modify qobject_ref() to assert on NULL
Date: Thu, 19 Apr 2018 15:37:06 +0200	[thread overview]
Message-ID: <CAJ+F1C+dGBWRaZ5GjtkLTm9SAWK9FZ=MByVicJ9WFxfPQU_q3Q@mail.gmail.com> (raw)
In-Reply-To: <8736zryb03.fsf@dusky.pond.sub.org>

Hi

On Thu, Apr 19, 2018 at 8:18 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> While it may be convenient to accept NULL value in
>> qobject_unref() (for similar reasons as free() accepts NULL), it is
>> not such a good idea for qobject_ref(), assert() on NULL. One place
>> relied on that behaviour (the monitor request id), and it's best to be
>> explicit that NULL is accepted there.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>>  include/qapi/qmp/qobject.h | 7 ++++---
>>  monitor.c                  | 2 +-
>>  2 files changed, 5 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
>> index befc945504..a0b2affb2c 100644
>> --- a/include/qapi/qmp/qobject.h
>> +++ b/include/qapi/qmp/qobject.h
>> @@ -73,9 +73,8 @@ static inline void qobject_init(QObject *obj, QType type)
>>
>>  static inline void *qobject_ref_impl(QObject *obj)
>>  {
>> -    if (obj) {
>> -        obj->base.refcnt++;
>> -    }
>> +    assert(obj);
>> +    obj->base.refcnt++;
>>      return obj;
>>  }
>>
>> @@ -103,6 +102,7 @@ static inline void qobject_unref_impl(QObject *obj)
>>
>>  /**
>>   * qobject_ref(): Increment QObject's reference count
>> + * @obj: a #QObject or child type instance (must not be NULL)
>>   *
>>   * Returns: the same @obj. The type of @obj will be propagated to the
>>   * return type.
>> @@ -112,6 +112,7 @@ static inline void qobject_unref_impl(QObject *obj)
>>  /**
>>   * qobject_unref(): Decrement QObject's reference count, deallocate
>>   * when it reaches zero
>> + * @obj: a #QObject or children type instance (can be NULL)
>>   */
>>  #define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
>>
>> diff --git a/monitor.c b/monitor.c
>> index 7dbc1f74b8..3a750208fd 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -4188,7 +4188,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
>>
>>      req_obj = g_new0(QMPRequest, 1);
>>      req_obj->mon = mon;
>> -    req_obj->id = qobject_ref(id);
>> +    req_obj->id = id ? qobject_ref(id) : NULL;
>>      req_obj->req = req;
>>      req_obj->need_resume = false;
>
> What's your argument that this is the only use of qobject_ref() that
> needs to be guarded now?

Right, that's the only one that is obvious, as it fails in test, and
the code is pretty obvious about id being optional.

For the rest, we have to rely on testing, and manual inspection of
qobject_ref() usage:

- block.c: guarded in bdrv_refresh_filename(), more tricky for
append_open_options(), as it depends if qdict values could be NULL
- block/blkdebug.c: depends if qdict values could be NULL,
full_open_options could NULL apparently, so should probably be handled
FIXED
- block/blkverify.c: guarded
- block/{null,nvme}.c: guaded, previous qdict_del() (actually
qdict_find()) guarantee non-NULL)
- block/quorum.c: if full_open_options can be NULL, we should handle it. FIXED
- monitor: optional "id" case must be handled, done in 2 places
  monitor_json_emitter(): only called with data != NULL, we could add
an earlier assert
  monitor_qapi_event_queue(): called from func_emit, by qapi events,
assert earlier during construction in qobject_output_complete()
- qapi/qmp-dispatch.c: if "arguments" exists, it can't be NULL during
json parsing
- qapi/qobject-input-visitor.c: guarded by assert in visit_type_any()
- qapi/qobject-output-visitor.c: guarded by assert in visit_type_any()
for qobject_output_type_any, guarded by assert() in
qobject_output_complete
- qmp.c: guarded, error out before if NULL
- qobject/q{list,dict}.c: can accept NULL values apparently, what's
the reason? how are you supposed to handle that?
- tests/*: let's consider this is covered by make check
- util/keyval.c: guarded, if (!elt[i]) before the ref

Except a very few corner cases, it looks quite safe to me. But, if
necessary, we can add if obj ? obj_ref(obj) : NULL for the dubious
cases.

-- 
Marc-André Lureau

  reply	other threads:[~2018-04-19 13:37 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-17 13:35 [Qemu-devel] [PATCH v5 0/5] Simplify qobject refcount Marc-André Lureau
2018-04-17 13:35 ` [Qemu-devel] [PATCH v5 1/5] qobject: ensure base is at offset 0 Marc-André Lureau
2018-04-17 18:17   ` Eric Blake
2018-04-18 16:45     ` Markus Armbruster
2018-04-18 16:58       ` Marc-André Lureau
2018-04-18 17:04       ` Eric Blake
2018-04-19  6:07         ` Markus Armbruster
2018-04-17 13:35 ` [Qemu-devel] [PATCH v5 2/5] qobject: use a QObjectBase_ struct Marc-André Lureau
2018-04-17 18:33   ` Eric Blake
2018-04-19  6:11   ` Markus Armbruster
2018-04-17 13:36 ` [Qemu-devel] [PATCH v5 3/5] qobject: replace qobject_incref/QINCREF qobject_decref/QDECREF Marc-André Lureau
2018-04-17 18:46   ` Eric Blake
2018-04-19  6:16   ` Markus Armbruster
2018-04-19 14:27     ` Marc-André Lureau
2018-04-17 13:36 ` [Qemu-devel] [PATCH v5 4/5] qobject: modify qobject_ref() to return obj Marc-André Lureau
2018-04-17 18:50   ` Eric Blake
2018-04-19  6:25     ` Markus Armbruster
2018-04-17 13:36 ` [Qemu-devel] [PATCH v5 5/5] qobject: modify qobject_ref() to assert on NULL Marc-André Lureau
2018-04-17 18:51   ` Eric Blake
2018-04-19  6:18   ` Markus Armbruster
2018-04-19 13:37     ` Marc-André Lureau [this message]
2018-04-19  6:44 ` [Qemu-devel] [PATCH v5 0/5] Simplify qobject refcount Markus Armbruster
2018-04-19 10:09   ` Marc-André Lureau
2018-04-19 11:48     ` Marc-André Lureau
2018-04-19 13:13       ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJ+F1C+dGBWRaZ5GjtkLTm9SAWK9FZ=MByVicJ9WFxfPQU_q3Q@mail.gmail.com' \
    --to=marcandre.lureau@gmail.com \
    --cc=armbru@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.