Secure Coding mailing list archives

Coding with errors in mind - a solution?


From: tholleb at teknowledge.com (Tim Hollebeek)
Date: Tue, 5 Sep 2006 11:10:51 -0700

 

-----Original Message-----
From: Pascal Meunier [mailto:pmeunier at cerias.net] 
Sent: Friday, September 01, 2006 7:41 AM
To: michaelslists at gmail.com
Cc: Tim Hollebeek; sc-l at securecoding.org
Subject: Re: [SC-L] Coding with errors in mind - a solution?

On 8/31/06 8:05 PM, "mikeiscool" <michaelslists at gmail.com> wrote:

His point, I think, is that if you wrap a series of 
statements in an 
try/catch block, you might not roll back every statement you needed 
to, or checked appropriate conditions.

For example:
try {
 openFile();
 getData();
 writeToFile();
 setSomeFlag()
 moveFile();
 deleteTempThings();
} catch(Exception e){
 ...
}

[...]

Ah, yes, I can see a bad (or under pressure) programmer 
lumping together the handling of exceptions that should be 
handled separately, or making just one giant try block so 
when there's an exception, even if you specify the type 
there's still ambiguity as to where it came from and 
therefore can't handle it properly.  That could be quite a 
mess.  Thanks.

Exceptions simplify the code? I don't think so. They also 
don't reduce 
code duplication [per se] you need to add extra functions, 
etc, to do 
that.

They can simplify the code because
-as previously mentioned by Tim, they separate error handling 
from normal logic, so the code is easier to read (it is 
simpler from a human reader's perspective).

But they only really "separate" the error handling if you have
one big try block, and that can make proper diagnosis difficult.
For example, in the above case, if you get a FileNotFound exception,
did it come from openFile or moveFile?  It may be possible to
figure that out, but the extra logic will be more than you would
have had if you had just checked the return value of the call.

-if an exception is handled several call layers above, you 
don't have to copy/translate and relay the error at each 
layer, with the attached loss of context and possible 
translation mistakes (error #3 in one layer/module may mean 
something different in another...).  So, there's less 
(duplicated) code.

But the intervening stack frames have to be (painfully) aware of
the fact that they might terminate abruptly.  Experience has shown
that getting this right is very hard, offsetting the benefits of
being able to quickly pop back up to a frame where the error can
be handled.

-It is common (and bad, IMO) practice for errors to be 
signified to callers by returning an out of range or 
different type (or null) value when something else is 
semantically expected.

This is especially true when there is only one value available
for all errors (like zero).  GetLastError/errno is a silly
substitute for not having another 'out' parameter, justified
on the basis that sometimes you don't care what the error was.
Except that you should!

Exceptions can be useful, but they really aren't what you want for
error handling, and are often cause as many problems as they cause.

What you really want is for all the (partial) side effects of a
function to disappear when it unrolls, but that's hard to do.
Even cleanup code is tough to get right due to the fact that
(A)(B)(A^-1) != B    
(can we reboot the universe with that feature disabled?  
It causes problems all over the place ...)

That said, Windows Vista will have transactions for file system/
registry modifications, so perhaps that will make life a bit easier...

-Tim




Current thread: