is_method_error versus call() errors

Thomaiyar, Richard Marian richard.marian.thomaiyar at linux.intel.com
Tue Sep 11 19:51:56 AEST 2018


In sdbus++ generated code we end up setting error_const for any issue 
(i.e. in the D-Bus daemon / server end).

catch(sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument& e)
     {
         sd_bus_error_set_const(error, e.name(), e.description());
         return -EINVAL;
     }

and in our sdbusplus (bus.hpp.in), the code is updated to throw the error

     auto call(message::message& m, uint64_t timeout_us = 0)
     {
         sd_bus_error error = SD_BUS_ERROR_NULL;
         sd_bus_message* reply = nullptr;
         int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
                                    &reply);
         if (r < 0)
         {
             throw exception::SdBusError(&error, "sd_bus_call");
         }

         return message::message(reply, _intf, std::false_type());
     }

i.e. for any error thrown in the D-Bus daemon(server), the client 
application call() will just throw SdBusError, and not the message 
object. Hence there is no way to perform is_method_error() on the 
message right?

Also, i believe even before throwing SdBusError(), 
sd_bus_message_unref(reply) has to be called, to make sure that messages 
are unref even for errors thrown from D-Bus daemon.

Let me know if i misunderstand the logic in current code.

Regards,

Richard


On 9/11/2018 3:19 AM, William Kennington wrote:
> This is something that is a little confusing about the semantics of
> sdbus. When using sd_bus_call(), it will only populate the returned
> message pointer if the dbus rpc succeeds. In the case where something
> fails at the dbus level, the sd_bus_call() method fails and the
> message is never populated. If we don't check for errors on
> sd_bus_call() but use sd_bus_message_is_method_error on the NULL
> message, we get an -EINVAL and treat that as an error. This behavior
> works fine if you only care that you had an error, but don't need to
> interpret the error and perform special case handling depending on the
> type. This is why I added the exceptions to sd_bus_call() so that we
> can parse out specific errors like -EBUSY or -EINTR, but handle the
> rest differently.
>
> sd_bus_message_is_method_error() is supposed to be used for checking
> if the server we are talking to sent an error response, not if the
> dbus layer had some kind of error. These errors are application
> specific and can be parsed out of a valid message if they exist.
> sd_bus_call() will still return success even if the server method sent
> a METHOD_ERROR type of message. You can't technically rely on
> sd_bus_message_read returning an error when reading from a
> METHOD_ERROR type of message. Practically though if your METHOD_ERROR
> message never have any content the read will fail since the message
> won't contain the expected data types. Unfortunately this means we
> will should keep all of the is_method_error checks and make sure c++
> exception handling is in place for all of the daemons.On Mon, Sep 10,
> 2018 at 9:18 AM Patrick Venture <venture at google.com> wrote:
>> Given:
>>
>> _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const
>> char *name) {
>>          assert_return(m, -EINVAL);
>>          if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
>>                  return 0;
>>          if (name && (!m->error.name || !streq(m->error.name, name)))
>>                  return 0;
>>          return 1;
>> }
>>
>> The failures from call() don't always set the reply (maybe don't ever,
>> but I didn't read it closely).  Which means, is_method_error() can
>> happen when the bus call itself was fine, so we need to check both IFF
>> we're going to read the response.
>>
>> I'm working on eliminating the new crashes from phosphor-host-ipmid
>> and other repositories, now that sdbusplus can except, which is not
>> caught even though there's an error case for is_method_error()
>> immediately after the call.
>>
>> In phosphor-pid-control, I dropped the is_method_error() check, but I
>> think it's still valid before trying to read() a message -- so I will
>> likely throw a patch adding that check.
>>
>> Patrick



More information about the openbmc mailing list