Date: Wed, 1 Apr 2009 09:36:09 -0700 From: "Matthew Fleming" <matthew.fleming@isilon.com> To: "FreeBSD Arch" <arch@freebsd.org> Cc: Marcel Moolenaar <xcllnt@mac.com> Subject: RE: On errno Message-ID: <06D5F9F6F655AD4C92E28B662F7F853E02930FBC@seaxch09.desktop.isilon.com> In-Reply-To: <FE53FDC4-6416-458C-A10C-C2C70A085C83@mac.com> References: <8321954E-5CFF-45F9-9F87-BE83659E4C8D@mac.com> <FE53FDC4-6416-458C-A10C-C2C70A085C83@mac.com>
next in thread | previous in thread | raw e-mail | index | archive | help
> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?06D5F9F6F655AD4C92E28B662F7F853E02930FBC>