qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/5] RFC: require error handling for dynamically created objects
@ 2024-10-31 15:53 Daniel P. Berrangé
  2024-10-31 15:53 ` [RFC 1/5] qom: refactor checking abstract property when creating instances Daniel P. Berrangé
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Daniel P. Berrangé @ 2024-10-31 15:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Peter Xu, Daniel P. Berrangé

With code like

    Object *obj = object_new(TYPE_BLAH)

the caller can be pretty confident that they will successfully create
an object instance of TYPE_BLAH. They know exactly what type has been
requested, so it passing an abstract type for example, it is a clear
programmer error that they'll get an assertion failure.

Conversely with code like

   void somefunc(const char *typename) {
      Object * obj = object_new(typename)
      ...
   }

all bets are off, because the call of object_new() knows nothing
about what 'typename' resolves to. It could easily be an abstract
type. As a result, many code paths have added a manual check ahead
of time

   if (object_class_is_abstract(typename)) {
      error_setg(errp, ....)
   }

...except for where we forget to do this, such as qdev_new().

Overall 'object_new' is a bad design because it is inherantly
unsafe to call with unvalidated typenames.

This problem is made worse by the proposal to introduce the idea
of 'singleton' classes[1].

Thus, this series suggests a way to improve safety at build
time. The core idea is to allow 'object_new' to continue to be
used *if-and-only-if* given a static, const string, because that
scenario indicates the caller is aware of what type they are
creating at build time.

A new 'object_new_dynamic' method is proposed for cases where
the typename is dynamically chosen at runtime. This method has
an "Error **errp" parameter, which can report when an abstract
type is created, leaving the assert()s only for scenarios which
are unambiguous programmer errors.

With a little macro magic, we guarantee a compile error is
generated if 'object_new' is called with a dynamic type, forcing
all potentially unsafe code over to object_new_dynamic.

This is more tractable than adding 'Error **errp' to 'object_new'
as only a handful of places use a dynamic type name.

NB, this is an RFC as it is not fully complete.

 * I have only converted  enough object_new -> object_new_dynamic
   to make the x86_64-softmu target compile. It probably fails on
   other targets.

 * I have not run any test suites yet, so they may or may not pass

 * I stubbed qdev_new to just pass &error_fatal. qdev_new needs
   the same conceptual fix to introcce qdev_new_dynamic with
   the macro magic to force its use

Obviously if there's agreement that this conceptual idea is valid,
then all these gaps would be fixed.

With this series, my objections to Peter Xu's singleton series[1]
would be largely nullified.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2024-10/msg05524.html

Daniel P. Berrangé (5):
  qom: refactor checking abstract property when creating instances
  qom: allow failure of object_new_with_class
  convert code to object_new_dynamic() where appropriate
  qom: introduce object_new_dynamic()
  qom: enforce use of static, const string with object_new()

 accel/accel-user.c               |  3 +-
 chardev/char.c                   |  5 +++-
 hw/core/bus.c                    |  2 +-
 hw/core/cpu-common.c             |  2 +-
 hw/core/qdev.c                   |  4 +--
 hw/i386/x86-common.c             |  5 +++-
 hw/i386/xen/xen-pvh.c            |  2 +-
 hw/vfio/common.c                 |  6 +++-
 hw/vfio/container.c              |  6 +++-
 include/qom/object.h             | 48 ++++++++++++++++++++++++++++++--
 net/net.c                        | 10 ++++---
 qom/object.c                     | 38 +++++++++++++++++--------
 qom/object_interfaces.c          |  7 ++---
 qom/qom-qmp-cmds.c               | 15 ++++++----
 system/vl.c                      |  6 ++--
 target/i386/cpu-apic.c           |  8 +++++-
 target/i386/cpu-sysemu.c         | 11 ++++++--
 target/i386/cpu.c                |  4 +--
 target/s390x/cpu_models_sysemu.c |  7 +++--
 tests/unit/check-qom-interface.c |  3 +-
 tests/unit/test-smp-parse.c      | 20 ++++++-------
 21 files changed, 151 insertions(+), 61 deletions(-)

-- 
2.46.0



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-11-01 11:33 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-31 15:53 [RFC 0/5] RFC: require error handling for dynamically created objects Daniel P. Berrangé
2024-10-31 15:53 ` [RFC 1/5] qom: refactor checking abstract property when creating instances Daniel P. Berrangé
2024-10-31 15:53 ` [RFC 2/5] qom: allow failure of object_new_with_class Daniel P. Berrangé
2024-10-31 19:09   ` Peter Xu
2024-11-01 11:29     ` Daniel P. Berrangé
2024-10-31 15:53 ` [RFC 3/5] convert code to object_new_dynamic() where appropriate Daniel P. Berrangé
2024-10-31 19:21   ` Peter Xu
2024-11-01 11:32     ` Daniel P. Berrangé
2024-10-31 15:53 ` [RFC 4/5] qom: introduce object_new_dynamic() Daniel P. Berrangé
2024-10-31 19:22   ` Peter Xu
2024-11-01 11:32     ` Daniel P. Berrangé
2024-10-31 15:53 ` [RFC 5/5] qom: enforce use of static, const string with object_new() Daniel P. Berrangé
2024-10-31 19:32   ` Peter Xu
2024-10-31 19:46 ` [RFC 0/5] RFC: require error handling for dynamically created objects Peter Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).