gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GError (Re: [Gnu-arch-users] "librifying" libarch)


From: Tom Lord
Subject: Re: GError (Re: [Gnu-arch-users] "librifying" libarch)
Date: Mon, 20 Oct 2003 18:00:38 -0700 (PDT)



    > From: Andrew Suffield <address@hidden>

    > On Mon, Oct 20, 2003 at 01:58:32PM -0700, Tom Lord wrote:

    > >            Heck, there's a much simpler solution that's just
    > >            as good as domain+code:

    > >                 typedef char * arch_error_t;

    > This is a fragile ABI.

That's crazy-talk, man.

Short answer: the whole point of the error_t definition I described is
to trick the linker into allocating a unique address-per-error.
Linkers don't (in general) know how to do that for integer constants
or enums.  The GError foo works around the same linker limitation by
performing a run-time allocation of a quark and replacing the error_t
type with a three-field structure.

Wouldn't it be nice if I could write foo.c:

        enum error_codes includes
        {
          foo_err_machine_caught_fire,
          foo_err_sysadmin_is_a_jerk,
        }

and you could write bar.c:

        enum error_codes includes
        {
          bar_err_comet_impact,
          bar_err_gravitational_constant_changed,
        }


and we could separately compile and link those together and wind up
with four distinct values for a variable of type `enum error_codes'
in "baz.c"?

But we can't do that.  GError says (in part) "Ok, then do some
run-time initialization" and my error_t says "Ok, well, the linker can
come pretty close by allocating addresses for global data rather than
enum values."

The only lossage of the error_t technique compared to errno-style
integers is that error values aren't going to be densely-packed small
integers (which, formally, errno doesn't guarantee but it's a
reasonable presumption) -- but the trade-off in error_t is that
separately developed code can be linked together, each part bringing
it's own error_t values to the table.

The only lossage of the error_t technique compared to GError-style
handling is that error values aren't guaranteed to be a densely-packed
near-the-origin subset of the cartesian 2d plane -- but the trade-off
for that is that separately developed code can be linked together
without imposing a need for run-time initialization of error domains
and without a tediously tiresome interface to manipulating error
valuess.




    > The pointer values are not portable between different processes, so
    > you'll have to use the string values for IPC. 

You've really deep-ended here.

No, if you wanted to exchange error codes, you wouldn't use
string-values for IPC - not in the way you presume.  For many
protocols, you would probably want to include the string in messages.
(I'd be fine with a rule that says an error string used to initialize
an error_t value should contain only graphical characters and blanks.)

By way of illustration, classic text-based IETF protocols tend to be
based on something more complicated than and quite different from mere
error codes: they tend to use "response classes" + "error messages":

        550 sdfljksdflsdjfsd: No such file OR directory.
        ^                       ^
        |                       |
        response class          error message


There's no error code in site there.  The response class tells a
reader what kinds of response/reaction make sense.  The message can be
forwarded to a user to give them a clue.   But in the application
generating that message, many quite distinct "error codes" might
result in that same message:  the client is not expected to be looking
for error codes, just response classes.

If you wanted to, in the error_t world, you could adopt a practice
which is the moral equivalent of:


        550 (782344) No such file OR directory.
        ^    ^                          ^
        |    |                          |
        |    error id               error message
        |    (the address of
        |     the error string,
        |     usually)
        |
        response class
        (optional, I guess)


and, if your protocol involves a subset of "standard error codes"
then:


        550 ($1) No such file OR directory.
        ^    ^                          ^
        |    |                          |
        |    error id               error message
        |    (a standard encoding
        |     for this error)
        |
        |
        response class
        (optional, I guess)

and leave it up to your marshalling/unmarshalling code to puzzle out
what $1 refers to.   This assumes that the recipient has some use for 
the error code as distinct from the response class.

There's a very tiny subset of IPC in which it would make sense (say,
via a shared-memory region) to pass an integer errno value with no
marshalling/unmarshalling steps: processes related by fork (but with
no execs).  And, guess what, my error_t works perfectly fine in that
case (for error codes present in the ancestor process) but GError
doesn't.



-t





reply via email to

[Prev in Thread] Current Thread [Next in Thread]