On errno
    Matthew Fleming 
    matthew.fleming at isilon.com
       
    Wed Apr  1 09:48:08 PDT 2009
    
    
  
> Augmentation seems logical. Does anyone know if this has been done
> in some OS already?
AIX version 6.0 has a kerrno_t type which contains the 8-bit standard
error code, as well as basically implementation defined bits that define
where the error came from.  This is for the kernel and kernel
extensions; for binary and source compatibility reasons the existing
interfaces could not be changed, but new interfaces used the new return
type.
I wasn't completely happy with the way it was done, but basically
<sys/kerrno.h> defined a 12-bit block of the kerrno_t that defined which
"namespace" the error came with, and parceled out a bunch for the known
AIX components with a bunch of unused ones too.  So a kerrno_t looked
like:
(32-bit)
1b |
[12 bits identifying a larger namespace like which header] |
[11 bits identifying which specific error return from that header] |
[8 bits for errno]
(64-bit)
0xEEEE |
0x0000 |
[12 bits identifying a larger namespace like which header] |
[12 bits identifying which specific error return from that header] |
[8 bits for errno]
Using 0xEEEE was an eye-catcher, plus the error was negative.  Similarly
the 32-bit errors are negative, which means that functions can continue
to return single positive scalars in success cases that contain
meaningful information, instead of requiring a reference parameter.
So e.g. kerrno.h parceled out the namespace like:
__SYSVMM_BLOCK_00		0x008
__SYSPROC_BLOCK_00	0x010
__DMA_BLOCK_00		0x018
...
If a component wanted to use one "namespace" per header file, there was
generally room for it.
And then in each shipped header file were unique defines for each reason
code, like:
#define EINVAL_XMEMDMA_BADADDRESS	KERROR(EINVAL, __DMA_BLOCK_00,
0x001) #define ENOENT_XMEMDMA_YOUSUCK	KERROR(ENOENT, __DMA_BLOCK_00,
0x002)
(non-shipped headers didn't always need to enumerate the unique error
codes in the header, but instead in the source file, because the callers
weren't expected to look for a specific error)
The code then returned somewhat ugly looking codes like
EINVAL_XMEMDMA_BADADDRESS.  But they could be explicitly compared.  The
kernel also had an awk script that generated a .txt file that listed all
the names and the hex value they were defined as; this was useful for
doing lookups of whatever error codes we were looking at at the time.
Something better could probably be done there.
I don't recall that AIX finished out the story with user-space.  But
these kerrno_t's were extremely useful for debugging any component that
had plumbed itself fully; no more guessing at the 23 reasons it could
return EINVAL; no more wondering in which subroutine the error was
produced.
So yeah, it isn't perfect and there's probably a better way, but it was
definitely better than nothing.
Discuss. :-)
Cheers,
matthew
    
    
More information about the freebsd-arch
mailing list