[ANNOUNCE] D-Bus 1.0 RC 1 (0.93) released

Havoc Pennington hp at redhat.com
Mon Sep 18 06:50:16 PDT 2006


Hi,

Kimmo Hämäläinen wrote:
 > I'm just telling you something I have learned while developing an
 > embedded Linux system. In such a swapless, low-RAM system we sometimes
 > might want to deny memory allocations of an application to prevent the
 > whole system from crashing. Technologies such as Glib (which just calls
 > abort() on OOM) do not make this easy (actually pretty impossible).
 > D-Bus is used also in the lowest levels, so it should allow extremely
 > robust programs.
 >
 > If there is a small thing we can do to make the developer's life easier,
 > why not do it?

The basic issue is that it isn't a small thing at all. To do this, we 
have to:
  - add a DBusError to *every* function, quite possibly doubling the API
    size with tons of _with_error variants
  - remove the ability to shrink the library significantly, since
    --disable-checks/--enable-checks would now be in the API contract
  - conduct certain inefficient checks and and over and over on the same
    data. So for example appending a string to a message could require
    validation several times as it moves through different functions in
    the API. _expensive_ compared to just validating untrusted data one
    time as it enters the address space (from disk or network).

What would happen in this case I'm very sure:
  - people would quickly get in the habit of passing NULL for "useless"
    and "can't happen" DBusError
  - they would then fail to use DBusError in the cases we have now,
    i.e. when it does in fact have a purpose in reporting a
    compile-time-undetectable error condition such as IO errors

If you really think I'm wrong, nothing says these _with_error() variants 
have to be in libdbus itself; they could as easily be a binding. So 
someone could offer a library that provides just what you say. If lots 
of people were using that library then we'd have to consider whether to 
include it in main libdbus. But I doubt a lot of people would be.

> Yes, it's a bug, but I don't understand why D-Bus library should make it
> more difficult to fix the bug.

These checks are there to make it easier. The check prints out a warning 
about exactly what is wrong, and the fix is almost always trivial.

> Think about the time when developing the
> client program -- the more error codes/messages the easier for the
> developer.

That's why return_if_fail prints an error message

> Also, there should be a way to handle these errors in
> run-time because some of us (with bad genes?) make mistakes that are not
> caught in development time (asserts are not an alternative here).

If you're going to write:
try {
    dbus_blah(foo);
} catch (NullPointerException e) {

}

then you may as well write:
if (foo != NULL)
    dbus_blah(foo);

IOW you are proposing:

try {
    dbus_blah(foo); // this is buggy
} catch (BugInProgramException e) {

}

catching null pointer exception is definitely frowned upon in Java too; 
catching a bug instead of fixing it is just weird. Either way you have 
to modify the code!

> This crashing client library is another thing I don't understand. I
> simply don't understand why the library should 'punish' the user instead
> of helping him to develop robust programs. If there is a crash, at least
> the reason should be told (e.g. by returning an error code). I believe
> this is a must for some high-level bindings as well, so that they can
> raise an exception instead of just crashing.

High-level bindings must validate sufficiently to be sure they don't 
pass anything invalid to libdbus.

> The contract must tell exactly what can be returned and when.

The contract is something like:
  - the allowed args are xyz. if those are passed, abc happens.
  - if you pass non-allowed args, dbus will make a best effort
    to notice and print an explanatory warning, but has no
    defined behavior

Note that in C/C++, there is no robust RTTI and anything can segfault if 
touched improperly. So the contract for non-allowed args is *at most* 
that certain common ones are handled; it's impossible to generically 
handle anything passed in.

  There is
> no disclaimer 'your program must be bug-free'. What other API than the
> D-Bus API requires this?

In C/C++, pretty much all of them. The entire glib+gtk stack for 
starters, but many others effectively do. Some use the "print warning 
and enter undefined mode" approach and some just crash if given invalid 
args. cairo has its own trick, which is that it stops drawing anything. 
So if you pass invalid args nothing gets drawn after that and you have 
to try and figure out which function is the problem. I prefer the 
warning ;-)

Havoc



More information about the dbus mailing list