Page 1 of 2

How do you handle your Errors?

Posted: Sat Aug 18, 2012 5:54 pm
by VolTeK
This thread is mean't to give out ideas to other developers of their own projects of how to handle certain error events.

In this thread, post a system error your OS would encounter, and how would your OS would handle it. Why do you think your means of handling the problem is the best solution? Sure there are simple ways of handling average errors, try and come up with complex situations, or complex ideas of how to handle a situation that seems impossible to get by (A system stop being required at times) that you think you can find a solution to that would keep it going (Staying stable, and operational). I do realize there are some errors that have no solution but a crash screen and reboot, so try and stay away from those.


This is mean't to be educational to others who probably haven't encountered the same error, and to help them for when they do.

Re: How do you handle your Errors?

Posted: Sat Aug 18, 2012 6:05 pm
by Jezze
Dealing with errors and handling them is a very difficult and often overlooked problem.

I don't think their exist some sort of standardized way to handling them because an error can occur in so many different ways. It is very much an iterative process meaning that depending on what type of error you receive you need to handle each and every one of them differently and if the solutions is unsatisfactory you need to improve the handling of them. The only common ground I can think of is to log each error in a unified way. Other than that I think I'm afraid there is no good or general rule of thumb you can follow here.

Re: How do you handle your Errors?

Posted: Sat Aug 18, 2012 6:20 pm
by OSwhatever
For OS development, a JTAG debugger is king, even better with MIPI or ETM recording ability. Unfortunately hobbyists might not have this luxury and therefore they have to find other ways. Emulators or HW with remote debugging availability is also very useful which can be easier to obtain.

In general, in order to get the errors, make sure you trap unhandled expeditions early in the project. Just having a register dump can very useful.

Re: How do you handle your Errors?

Posted: Sat Aug 18, 2012 7:40 pm
by bluemoon
My general rule is:
For service provider: If an error occurs, the function should have no side effect, and return negative error code.
For error handler: check the return value.

And this apply on nested layers of framework.

Re: How do you handle your Errors?

Posted: Sat Aug 18, 2012 8:29 pm
by gravaera
Yo:

Nope, I don't handle my errors. I leave them as is and move on. Progress waits for no-one.

--Peace out,
gravaera

Re: How do you handle your Errors?

Posted: Sun Aug 19, 2012 1:44 am
by rdos
The hardest errors to handle is sudden device-removal, like floppy discs or USB-discs. These are hard because the OS needs to build-up a complex file system structure, and might be in the middle of updating something when the device becomes unavailable.

For standard errors, all APIs use CY flag for error signalling, and doesn't give any error-codes. Thus handling errors from the RDOS API is simple: Either something succeeded or it didn't, no code required to figure out why. :mrgreen:

Re: How do you handle your Errors?

Posted: Sun Aug 19, 2012 5:10 am
by JamesM
I don't like propagating errors through negative return values.

Errors often appear in helper functions, and it can be useful for these helper functions to have a proper (non-success/fail) return value. Until C gets multiple return values, I have a function "set_errno()" which sets a thread-local variable (in an efficient way).

Functions therefore only have to propagate success or failure, and the failure mode can be read out of a thread local variable with "get_errno()".

Re: How do you handle your Errors?

Posted: Sun Aug 19, 2012 4:00 pm
by Owen
I'm a C++ nut.

Why do I say this? Because I have a standardised method of handling errors:

throw AnException();

I have a very "don't repeat yourself" attitude. Thats why I make pervasive use of RAII: For every resource managed by RAII, that's one less thing to go wrong. I love RAII: It really does result in a simplification of program code. It's not perfect, but it's close. Outside C++ (and Objective-C*), Go is probably the language which comes closest with Goroutines, but it still takes code on top of the normal program flow to handle cleanup.

I reserve catch blocks for *handling* exceptions: in general, I find their use to handle *cleanup* is in general a mistake, as it indicates that the lifetime of a resource is encoded in the program's behaviour rather than in its structure.

That said, RAII on its own isn't a panacea: it fails to handle cases involving mutable state on its own. However, it gets you at least 75% of the way, because most state change is resource acquisition or release, and most of the time you can get the next 15% of the way by restructuring things so that you acquire resources up front and then "commit them" with state changes at the end.

Still, I think that most of the time exception handling beats error code returns for cleanliness and code clarity. Some people say they dislike it, because it "hides behaviour from you", but I think that its mostly a matter of being used to error code handling. You have to get used to the change in structure from "Do something, then if that fails, undo it" to "Do something, then commit the results"

* Through it's almost-identical-to-C++ exception model and NSAutoreleasePool

Re: How do you handle your Errors?

Posted: Sun Aug 19, 2012 4:29 pm
by eryjus
JamesM wrote:[...], I have a function "set_errno()" which sets a thread-local variable (in an efficient way).
I like it. Gonna "borrow" the idea!

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 4:45 am
by JamesM
Owen wrote:I'm a C++ nut.

Why do I say this? Because I have a standardised method of handling errors:

throw AnException();

I have a very "don't repeat yourself" attitude. Thats why I make pervasive use of RAII: For every resource managed by RAII, that's one less thing to go wrong. I love RAII: It really does result in a simplification of program code. It's not perfect, but it's close. Outside C++ (and Objective-C*), Go is probably the language which comes closest with Goroutines, but it still takes code on top of the normal program flow to handle cleanup.

I reserve catch blocks for *handling* exceptions: in general, I find their use to handle *cleanup* is in general a mistake, as it indicates that the lifetime of a resource is encoded in the program's behaviour rather than in its structure.

That said, RAII on its own isn't a panacea: it fails to handle cases involving mutable state on its own. However, it gets you at least 75% of the way, because most state change is resource acquisition or release, and most of the time you can get the next 15% of the way by restructuring things so that you acquire resources up front and then "commit them" with state changes at the end.

Still, I think that most of the time exception handling beats error code returns for cleanliness and code clarity. Some people say they dislike it, because it "hides behaviour from you", but I think that its mostly a matter of being used to error code handling. You have to get used to the change in structure from "Do something, then if that fails, undo it" to "Do something, then commit the results"

* Through it's almost-identical-to-C++ exception model and NSAutoreleasePool
Out of interest, how have you solved the "exceptions aren't kernel thread reentrant" problem?

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 4:51 am
by Owen
JamesM wrote:Out of interest, how have you solved the "exceptions aren't kernel thread reentrant" problem?
"kernel thread reentrant"? I'm not quite sure what you're getting at with that question.

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 8:48 am
by JamesM
Owen wrote:
JamesM wrote:Out of interest, how have you solved the "exceptions aren't kernel thread reentrant" problem?
"kernel thread reentrant"? I'm not quite sure what you're getting at with that question.
As far as I recall, the stack unwinding mechanism from libstdc++ is only reentrant across pthreads (uses pthread_setspecific?). I can't fully remember but knew there was some barrier to using exceptions in a homebrew kernel.

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 10:51 am
by Owen
JamesM wrote:
Owen wrote:
JamesM wrote:Out of interest, how have you solved the "exceptions aren't kernel thread reentrant" problem?
"kernel thread reentrant"? I'm not quite sure what you're getting at with that question.
As far as I recall, the stack unwinding mechanism from libstdc++ is only reentrant across pthreads (uses pthread_setspecific?). I can't fully remember but knew there was some barrier to using exceptions in a homebrew kernel.
I use a modified version of Pathscale's libcxxrt. Presently, it's modified to use C11 threading primitives instead of pthreads (so that when used in userspace it won't drag in any part of the POSIX emulation layer); I can see it being customised slightly further in order to better abstract it from the TLS system (thereby I can modify it to make direct access to a member of the kernel Thread class)

My intention is to upstream these changes

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 1:17 pm
by palk
JamesM wrote:Until C gets multiple return values...
Like this?

Code: Select all

typedef struct {
	uint32_t value;
	_Bool valid : 1;
} uint32_v;

uint32_v foo(void *bar) {
	uint32_v invalid = { .valid = 0, };
	if (bar == NULL)
		return invalid;
	// do something
	uint32_v result = {
		.valid = 1,
		.value = whatever,
	};
	return result;
}

Re: How do you handle your Errors?

Posted: Mon Aug 20, 2012 1:51 pm
by gerryg400
In my kernel I use exceptions, coded in C and implemented with setjmp/longjmp. Generally the details are hidden inside my kernel library so that for example calling

Code: Select all

kcopy_fromuser(currt, d, s, n);
will return a simple EFAULT if the user passes a bad address for 's' and somehow causes a page fault or the like.

I haven't needed nested exceptions yet. My kernel is a very simple microkernel.