[haiku-development] Re: Error Handling - TLS and Rich Layered Error Explanations

  • From: "Alexander G. M. Smith" <agmsmith@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Wed, 15 Sep 2021 13:13:03 -0400

On 2021-09-15 3:16 a.m., Axel Dörfler wrote:
> Not having a consistent API is not a good idea, but if you notice that this new way is actually better than before, it would still make sense to move into this direction, and aiming for consistency in the future, again, kit by kit.

Exceptions or status_t error codes could both use a rich layered error message system, in an almost orthogonal way.  You'd still have the error codes (keeping consistency with the current API) or exceptions happening, but on the side (rather than being returned directly) there would be a layered rich error explanation.  The best way to do that is to add the rich error messages to per-thread storage.

So I had a look at thread local storage (TLS) in Haiku.  It seems to set aside per-thread space for an array of 64 pointer sized values, which you can get to by specifying an index number.  Digging under the hood, on x86 processors TLS seems to be wherever segment register FS points, which is initialized from thread->user_local_storage, which is taken from the thread's stack after the user stack space, which is in a per-thread memory area.  The first few of the 64 slots are used for system things (see https://git.haiku-os.org/haiku/tree/headers/private/system/tls.h), like pointers to the thread structure, and there's even a TLS_ERRNO_SLOT one for Posix errno handling!  We just have to add one for the rich error structure and initialize it in arch_thread_init_tls() or rely on the default zero value (only system TLS slots are zeroed - would it be convenient to have the user ones zeroed too?).  Alternatively, we can stuff it into the kernel Thread structure (there's one per thread, which is what we need).

Then whenever you wanted to add an error explanation to the stack of text, you'd call a function that appends a string to the TLS storage, such as BRichErrorAppend(const char *message).  There would be a BRichErrorClear() to reset the message (called only by lowest level functions, possibly then appending strerror_r(code) to get a string for classic error codes).  And a const char *BRichErrorGet() to return the stack of errors as a string.

The first hack implementation is to use a BString as the object, and just prepend messages with a linefeed between them (so the highest level error message is first).  Though if the Haiku C++ runtime isn't available (could happen), the second hack is to do it with malloc and low level string copying operations.  A stack of more structured objects could be used, perhaps with separate fields for error codes for each level, but it would be simpler to just use a string and have tabs to separate fields (error code in ASCII, message text) and linefeeds to separate records.  Deallocate it in thread_exit().  Though it could be useful to let it linger a bit in the thread_death_entry structure and let people retrieve the error messages after the thread ends, like they can do with status codes.

- Alex

Other related posts:

  • » [haiku-development] Re: Error Handling - TLS and Rich Layered Error Explanations - Alexander G. M. Smith