How do you handle your Errors?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
brunexgeek
Member
Member
Posts: 45
Joined: Wed Dec 25, 2013 11:51 am

Re: How do you handle your Errors?

Post by brunexgeek »

I return a negative error code or zero on success. I try to be consistent with return values in my API's, thus almost all functions returns an error code (sometimes I use positive values to return sizes like in C standard library). But I have some exceptions, like functions returning a pointer instead (NULL if some error occurred).
JamesM wrote:... I have a function "set_errno()" which sets a thread-local variable ...
I don't use this technique in my kernel/OS (yet?), but I did in many other developments. I think it's a good solution too and allow you to provide some extra useful information, like a specific error message, line number and filename. Someone can say I can simply put this in a log file, but sometimes I don't want to log every "instance" of an error (I can decide if I will log it in another function).
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: How do you handle your Errors?

Post by rdos »

IMO, returning negative error codes is the worse of all solutions. Then you can no longer test return values from procedures as if they are boolean, and you need different code to check for pointers (0 = not ok) and for error returns (0 = ok). It also creates horrible code like if (!someproc()) success, which is highly error-prone and non-intuitive.

The idea to use C++ exception handling has merits, but it doesn't work between separately compiled drivers, and between kernel and user-space, which limits it's utility.
brunexgeek
Member
Member
Posts: 45
Joined: Wed Dec 25, 2013 11:51 am

Re: How do you handle your Errors?

Post by brunexgeek »

rdos wrote:IMO, returning negative error codes is the worse of all solutions. Then you can no longer test return values from procedures as if they are boolean, and you need different code to check for pointers (0 = not ok) and for error returns (0 = ok). It also creates horrible code like if (!someproc()) success, which is highly error-prone and non-intuitive....
Edit: I think logical tests with this kind of return (using zero for success and non-zero for failure) is not correct. Logical tests should be used with..."logical" return values (zero means failure and non-zero success). Maybe with pointers in which NULL means failure.

I agree with you about the problem with different codes for check pointers and errors, but IMO that's not too bad as you said.

BTW I don't use something like "if (!someproc())". I prefer more explicit error checking like:

Code: Select all

void *ptr;
int result;
...
if (ptr == NULL) ...
if (result < 0) ...
Last edited by brunexgeek on Mon Jan 13, 2014 5:02 pm, edited 1 time in total.
User avatar
b.zaar
Member
Member
Posts: 294
Joined: Wed May 21, 2008 4:33 am
Location: Mars MTC +6:00
Contact:

Re: How do you handle your Errors?

Post by b.zaar »

brunexgeek wrote:

Code: Select all

void *ptr;
int result;
...
if (ptr == NULL) ...
if (result < 0) ...
I prefer this way. It's fast and simple and when reading the code you understand the flow easily. If an error occurs then you can do a more detailed examination of the errno in whatever format that it may be stored. Usually a return value will either be a positive or a pointer so this works for the majority of functions.

In assembly I miss the old JC on error from a interrupt. I don't set carry in my asm functions as C can't check it quickly like a negative return value.
"God! Not Unix" - Richard Stallman

Website: venom Dev
OS project: venom OS
Hexadecimal Editor: hexed
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

Re: How do you handle your Errors?

Post by VolTeK »

--
Last edited by VolTeK on Thu Feb 06, 2014 8:14 pm, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: How do you handle your Errors?

Post by Combuster »

My system calls should return success status in CF. But instead of that, 90% of them actually panic for now to force me to fix the calling code.

The remainder of the system and driver interface (which is both the largest part and fully IPC-based) passes tuples with information that end up in callback functions, and you won't find any C-style return value in that part system. Instead there will be one of two separate functions called as an result: one for the success case, and one for the error case. This also means you can never forget an error.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
rdos
Member
Member
Posts: 3276
Joined: Wed Oct 01, 2008 1:55 pm

Re: How do you handle your Errors?

Post by rdos »

b.zaar wrote: In assembly I miss the old JC on error from a interrupt. I don't set carry in my asm functions as C can't check it quickly like a negative return value.
If you have a decent C compiler, it's not hard to decode CF from syscalls. I still use the CF for success / failure. I even support non-implemented functions by having a default-stub that just returns with CF set. It works because all syscalls must pass parameters in registers, and all syscalls use CF for success / failure.

The problematic issue typically is to set CF to the correct value from a C handler procedure. I think that it works easiest to simply define the entry-points for all syscalls in assembly, and then let them call C code to handle complex things. Otherwise the code gets really strange and hard to understand.

It would be far better if the C compiler instead could define a "success" variable (preferently of boolean type), which is implemented with CF on x86. That shouldn't be that hard to do, and it would create more readable code. After all, it only takes one instruction to test CF, while it takes two to check a register for being 0.
User avatar
nerdguy
Member
Member
Posts: 70
Joined: Wed Oct 30, 2013 8:11 am

Re: How do you handle your Errors?

Post by nerdguy »

I should be ashamed of this, but even for handling errors I have method called trial-and-error.
That works pretty nice even in real life, but is not always dependable :P
Nah, usually I first look at the region where the fault is suspected to reside, next I randomly
insert some string print code like : 'Stage 1 Complete', next I again see where it stops,
doing this a few times gets me the code that has a fault, next I hear Bochs shouting, usually on this stage
I know what the problem is, I RTFM for a while and that tells me where I am going wrong.
When you say, "I wrote a program that crashed Windows," people just stare at you blankly and say, "Hey, I got those with the system, for free." - Linus Torvalds
64 bit Kernel in early development
http://github.com/nerdguy12/core64
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do you handle your Errors?

Post by iansjack »

I'm afraid you seem to have misunderstood the topic being discussed.
User avatar
elderK
Member
Member
Posts: 190
Joined: Mon Dec 11, 2006 10:54 am
Location: Dunedin, New Zealand
Contact:

Re: How do you handle your Errors?

Post by elderK »

I'm rich in the ways that I can handle errors as my kernel is implemented in Scheme. I can "return" multiple values or throw around exceptions.

Generally, I dispatch to different functions depending on the outcome of a call. When a function calls another, it tells the callee who it should call next. "Returning" a value is nothing but an illusion as the functions never return. They simply pass their results to their successors when they invoke them.

This mechanism is called "continuation passing style" and I've found it to be both very useful and very powerful.

In the case mentioned directly above, the callee has only one successor. You can, however, have a function that accepts as many targets as there are error conditions. So, it goes to k1 on success, k2 on read timeout, k3 on allocation failure, etc.

~K
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: How do you handle your Errors?

Post by alexfru »

The main problem with errors is not detecting and passing them, but figuring out what to do with them, how to recover from them if at all possible. And this gets worse if the information about errors gets lost while being passed between the layers of software. It's also pretty bad if you're using a 3rd party piece of code and you have no idea what errors it can return and what they actually mean.

Say, file writing fails. Why? Did the disk become full? Did you reach a quota? Did the file reach the maximum size allowed by the FS? Did the FS get corrupted? Did the media get corrupted (bad cluster, etc)? Did you lose access rights in the process? Did you lose connection with a remote file server? Did the remote file server misbehave and if it did why did it and what can you do about it? Did you lose access rights to anything between you and the file (all the network stuff)? Did the local and remote times go out of synch and affect network protocol operation? Were there too much activity on the network and/or the server that precluded the write request from being satisfied in a reasonable time period and you got a timeout? There's probably a bunch more cases why things can fail. Now, if you don't get a descriptive enough error code/message or if it doesn't let you differentiate different causes, you don't really know what you can do about the error. Next comes the question about the context. Was it a user file? Can you properly inform the user of the problem and suggest a workaround/fix/etc? Is giving too detailed error information a good thing from security standpoint, and if it is not, how do you choose between usability and security? Was it a system file? If it was, is it some critical file that you absolutely must have r/w access to? If you must, you must stop and shut down the OS, but can you still store the error in the log or not (ditto for crash dumps)? If it's not something that critical, what happens if you log the error and continue? Are there any security implications of ignoring the error? What are they? What can you do about them?
Post Reply