Error handling in C

A

arnuld

Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
 
E

Eric Sosman

arnuld said:
Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

If there's a good document on the topic, I haven't seen it.
But I'll offer a few thoughts; take 'em or leave 'em.

There are two aspects to error handling: Detection of the
error condition and response to it. The first is dictated by
the API you're using: A function is documented to return NULL
or to set a global variable to 0xBaddBadd or whatever, and it's
up to you as the function's caller to make the indicated test.
If you're writing your own functions and want to report errors
from them, you can choose whatever means you like; consider the
other existing functions you use and imitate the style of those
you find easiest to get along with.

Once the error is detected, the response is a much thornier
problem. It has more to do with the structure of your program
and with the way the program is used than with the error itself.
Often, you want to get back to a "neutral state" where a user
can try the operation again, or try a different operation. But
for some programs there may be no "user:" a program that runs
unattended can't very well ask Higher Authority what to do if
something goes wrong. This is an area of great difficulty.

Some languages provide frameworks that favor a particular
style of error handling, things like "exceptions" in C++ or
Java, for example. C doesn't offer much of this sort of thing,
which is sometimes a curse and sometimes a blessing.
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

If you can write specifications this clearly and precisely,
you'll have a brilliant and successful career -- in management.
 
N

Nick Keighley

Can anyone point me to some online/offline document on error handling in C?

I've never seen a good one. Doesn't mean there isn't one, just I've
never seen it.
I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

yeah, error handling in C can be a pain. Especially if you've used
something with exceptions.

You might end up with something like this:-

<code>
int activesock (const char *host, int port, const char *protocol)
{
struct hostent *phe;
struct servent *pse;
struct protoent *ppe;
struct sockaddr_in sin;
int s, type;

memset (&sin, 0, sizeof sin);

sin.sin_family =AF_INET;
sin.sin_port = htons (port);

/* map host name to ip addr allowing for dotted decimal */
if ((phe = gethostbyname (host)))
memcpy (&sin.sin_addr, phe->h_addr, phe->h_length);
else
if ((sin.sin_addr.s_addr = inet_addr (host)) == INADDR_NONE)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
host entry\n", host);

/* map protocol name to protocol number */
if ((ppe = getprotobyname (protocol)) == 0)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
protocol entry\n", protocol);

/* use protoicol to choose socket type */
if (strcmp (protocol, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;

/* allocate a socket */
/* s = socket (PF_INET, type, ppe->p_proto); */
s = socket (PF_INET, type, DEFAULT_PROTOCOL);
if (s < 0)
raise_report (LEVEL_FATAL, "activesock", "can't create socket:
%s\n", strerror (errno));

/* connect to the socket */
if (connect (s, (struct sockaddr *)&sin, sizeof sin) < 0)
raise_report (LEVEL_FATAL, "activesock", "can't connect to %s.
%d: %s\n", host, port, strerror (errno));

return s;
}
</code>


basically you have to check the return value of every function.
But then that's good for you. Much as eating your vegetables and
drinking 2 pts of water is good for you.

In the above raise_report() writes to a log file and possibly
terminates the program.

A language with exceptions can look much nicer

<code>
DEFAULT_PROTOCOL = 0

sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM,
DEFAULT_PROTOCOL)

if len (sys.argv) < 2 :
host = "localhost"
else:
host = sys.argv [1]

sock.connect ((host, 8702))
</code>

But, of course, exceptions have their own pitfalls.

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

I don't think you can do this in C89. C99 has something like
__function__()
(I can't rememeber the exact spelling). My report routine above
takes a parameter for the function name. To be honest __FILE__ and
__LINE__ are usually good enough for me. Ok you don't want the user
to
see file and line, but then you don't want him to see function either.

One trick is to have your functions return an error value.

Rv do_big_thing()
{
do_sub_thing1();
do_sub_thing_2();
return OK;
}

this can be nested

Rv do_big_thing()
{
if ((rv = do_sub_thing1()) != OK)
{
log_error();
return rv;
}

if ((rv = do_sub_thing_2()) != OK)
{
log_error();
return rv;
}

return OK;
}

with suitable macro trickery this reduces to

Rv do_big_thing()
{
CHECK_CALL (do_sub_thing1());
CHECK_CALL (do_sub_thing_2());
return OK;
}

of course I now have a nasty macro, a global variable and a function
with multiple exits.

The price of greenspunning
 
J

James Kuyper

arnuld wrote:
....
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

In C99 you can use the pre-defined identifier __func__. When used, it
behaves exactly as if the following declaration had been inserted
immediately after the '{' at the start of the enclosing function:

static const char __func__[] = "function-name";

This feature was not available in C89, and I know of no way to do what
you're asking for without making use of __func__.
 
J

Joachim Schmitz

Nick said:
On 19 Nov, 13:11, arnuld <[email protected]> wrote:

I don't think you can do this in C89. C99 has something like
__function__()
(I can't rememeber the exact spelling).

__func__ and it's a string, not a macro (and not a function like macro
either)

I once had a hard time searching for in in the standard. Searching for
_func_ works and finds
_ _func_ _ (with a small space bewteen the _)

bye, Jojo
 
B

Ben Bacarisse

arnuld said:
Can anyone point me to some online/offline document on error handling in C
?

I am not aware of one, sorry.
I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

A common error I used to see in people starting out is to write the
program as if all is well and then, later, try to put the error
handling in. This does not work in C. You have to design the program
to handle all the failures you care about from the start. If you
haven't done this then, no matter how painful it may seem, you will
probably be better off starting over (you will be able to re-use bits
you've written so it is only the design you must re-do).

Most things work only one way but can fail in numerous ways. This
means there is often more code to handle errors than anything else.
If your algorithms are reasonably complex there may be a fair balance,
but a server that does something quite simple will be mostly error
handling code!
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

Do you mean something that simply reports errors? If so a starting
point might be (uses C99):

#define REPORT(...) do { \
fprintf(stderr, "In %s(): ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)

though I'd be inclined to turn this into a function with a simpler macro
as a wrapper.
 
D

dj3vande

Eric Sosman said:
C doesn't offer much of this sort of thing,
which is sometimes a curse and sometimes a blessing.

That one sentence, presented without context, makes an excellent
summary of pretty much everything that people love and hate about C.


dave
 
M

Martin Ambuhl

arnuld said:
Can anyone point me to some online/offline document on error handling in C
?

I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(

Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

If you have a C99 implementation, the function name is the predefined
identifier __func__ which follows block scoping rules. Your code needs
nothing long or involved:

/* C99 example */
#include <stdio.h>

void whoami(void)
{
fprintf(stderr, "Function %s does almost nothing\n". __func__);
}

Many pre-C99 implementations provide a similar mechanism, but this will
often be a macro (__func__ behaves as if it were a block-scope pointer
to static const char[].). For example, if you use GCC 3.4 or later, its
special name __FUNCTION__ behaves like __func__, but for GCC 3.3 or
earlier __FUNCTION__ behaved like a string constant, just as __FILE__,
__DATE__, and __TIME__ were and still are string constants. In
implementations for which the functionality of the C99 __func__ is
approximated with a macro expanding to a string constant, the above
approach still works:

/* example of one non-standard C89 extension, where the predefined
macro __FUNCTION__ expands to a string constant */
#include <stdio.h>

void whoami(void)
{
fprintf(stderr, "Function %s does almost nothing\n".
__FUNCTION__);
}

There are other ways to use macros that expand to string constants which
are not available when using __func__, but for just that reason they
should be avoided. But here is an example that should continue to work:

#include <stdio.h>
#if !defined(__FUNCTION__)
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define __FUNCTION__ __func__
#else
#define __FUNCTION__ "<unknown>"
#endif
#endif


void whoami(void)
{
fprintf(stderr, "At line %d in " __FILE__ "\n"
"Translated at " __TIME__ "on " __DATE__ "\n"
"In function %s\n."
__LINE__, __FUNCTION__);
}
 
C

CBFalconer

arnuld said:
Can anyone point me to some online/offline document on error
handling in C ?

I am doing some Socket Programming in C and feeling a lots of
difficult in error handling :(

Sockets are not part of standard C, and are thus off-topic in
c.l.c. You can reference the standard in the following:

Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://c-faq.com/> (C-faq)
<http://benpfaff.org/writings/clc/off-topic.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf> (C99)
<http://cbfalconer.home.att.net/download/n869_txt.bz2> (pre-C99)
<http://www.dinkumware.com/c99.aspx> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
Also some time ago some one told me that when I get an error then
I can create a generic function which, when called within some
function will print the name of that function automatically or
something like that I forgot. It had lots of #define(s) . Can
someone write that for me ?

No, but here is all you need, from the standard (needs C99):

6.4.2.2 Predefined identifiers

Semantics

[#1] The identifier __func__ shall be implicitly declared by
the translator as if, immediately following the opening
brace of each function definition, the declaration

static const char __func__[] = "function-name";

appeared, where function-name is the name of the lexically-
enclosing function.53)
 
P

Peter

You'll find the return value of most library function calls return a -1 if
the call is unsuccessful, however you should check the "man" manual
documents for the return values for these calls. Most write error messages
to standard error. for example:

s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
perror("socket: allocation failed");
 
A

arnuld

There are two aspects to error handling: Detection of the
error condition and response to it. The first is dictated by
the API you're using: A function is documented to return NULL
or to set a global variable to 0xBaddBadd or whatever, and it's
up to you as the function's caller to make the indicated test.
If you're writing your own functions and want to report errors
from them, you can choose whatever means you like; consider the
other existing functions you use and imitate the style of those
you find easiest to get along with.


I have inclined mostly to use the return value from functions, 0 for
success and everything else for failure (mostly -1 ). The only one problem
is I want to exit most of the time, or you can day that is the way my
current program runs and for checking error conditions at 8 places I have
to put exit( EXIT_FAULRE) at 8 places along using __func__ as an argument
to fprintf().





If you can write specifications this clearly and precisely,
you'll have a brilliant and successful career -- in management.

ouch! ... I never thought of myself belonging to that ugly place :p
 
J

James Kuyper

arnuld wrote:
....
I have inclined mostly to use the return value from functions, 0 for
success and everything else for failure (mostly -1 ). The only one problem
is I want to exit most of the time, or you can day that is the way my
current program runs and for checking error conditions at 8 places I have
to put exit( EXIT_FAULRE) at 8 places along using __func__ as an argument
to fprintf().

In my personal opinion, using exit() to deal with a problem is seldom
the right approach. A function should almost always report any problem
that severe to it's caller, and let the calling routine decide how to
deal with it. This approach makes it easier to re-use code. A problem
that gives you reason to halt one program might, when it occurs in a
different program using the same subroutine, be a reason to clean
something up (free allocated memory, close open files, etc.) and try
something different. Note: the "other program" might very well be a
future version of the same program.

This even applies to main(). Much of the code that currently resides in
main() might, in some other program, become a subroutine of main().
Making the conversion is easier if you use "return EXIT_FAILURE;" rather
than "exit(EXIT_FAILURE);". The practical consequence are almost the
same, unless main() directly or indirectly calls itself.
 
E

Eric Sosman

arnuld said:
I have inclined mostly to use the return value from functions, 0 for
success and everything else for failure (mostly -1 ).

Reporting an error by returning a special value is a
widely-used approach, but it presents some difficulties.
Consider strtol(), for example: *every* value it can return
could be a legitimate result, so no value can serve as an
unambiguous and unaided error indicator. (This difficulty
afflicts lots of other systems where "data" and "metadata"
share the same channel; recall the "2600 Hz" phone phreakers
of a few decades ago.)

One solution is to separate the data and metadata channels,
which in C terms means using separate "function outputs" for
result and for status. For example, the function return value
could be the status indicator, with the result (if any) stored
via an argument pointer (or vice versa, of course).
The only one problem
is I want to exit most of the time, or you can day that is the way my
current program runs and for checking error conditions at 8 places I have
to put exit( EXIT_FAULRE) at 8 places along using __func__ as an argument
to fprintf().

Are you familiar with the Sixth Commandment?

http://www.lysator.liu.se/c/ten-commandments.html

For small simple programs where "succeed or die trying" is
reasonable error-response strategy, you may want to write a few
wrapper or helper functions to ease the burden[*]. For example,
if you've got a function func() that returns a negative integer
on failure and all you want to do is die when it fails, you can
write and call xfunc() instead:

int xfunc( ...parameters... ) {
int result = func( ...parameters... );
if (result < 0)
exit (EXIT_FAILURE);
return result;
}

A somewhat more flexible approach is to let the caller do
the error-checking but delegate the reporting to a helper
function:

/* helper */
void crash(const char *message) {
fprintf (stderr, "%s\n", message);
exit (EXIT_FAILURE);
}

/* caller */
result = func( ...arguments... );
if (result < 0)
crash ("unable to frammis the jim-jam");

A fancier crash() might also report information about the
location where the error was detected, and might even go so
far as to accept a full printf-style parameter list.

[*] A cautionary observation: If the error-checking grows
to be a large burden, it is likely that the program has also
grown past the stage where suicide as a recovery scheme is
appropriate. It follows that there's usually a limit to how
useful things like xfunc() and crash() can become: Their brevity
provides the most benefit to the programs that are too complex
to use them, and the small simple programs don't need that much
help anyhow!
 
C

CBFalconer

Peter said:
You'll find the return value of most library function calls return
a -1 if the call is unsuccessful, however you should check the
"man" manual documents for the return values for these calls. Most
write error messages to standard error. for example:

Please do not top-post. Your answer belongs after (or intermixed
with) the quoted material to which you reply, after snipping all
irrelevant material. See the following links:

<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/> (taming google)
<http://members.fortunecity.com/nnqweb/> (newusers)
 
S

saurabh

I have inclined mostly to use the return value from functions, 0 for
success and everything else for failure (mostly -1 ). The only one problem
is I want to exit most of the time, or you can day that is the way my
current program runs and for checking error conditions at 8 places I have
to put exit( EXIT_FAULRE) at 8 places along using __func__ as an argument
to fprintf().

If you want to exit most of the times,how about the following function..

/* take a var which stores your programm's name
(lets call it prog_name) */
void die(char* func_name,char* message) {
if(prog_name && func_name && message)
fprintf(stderr,"%s|%s|%s\n",prog_name,func_name,message);
else
fprintf(stderr,"prog_name|die|exiting due to unknown error");
exit(EXIT_FAILURE);
}
 
T

Tony

James Kuyper said:
arnuld wrote:
...
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?

In C99 you can use the pre-defined identifier __func__. When used, it
behaves exactly as if the following declaration had been inserted
immediately after the '{' at the start of the enclosing function:

static const char __func__[] = "function-name";

This feature was not available in C89, and I know of no way to do what
you're asking for without making use of __func__.

Unfortunately, one does not have any control of how that function name
string will look. (I have forgotten how it DOES look since I have a macro
that inserts the declaration shown above with the format I want). __FILE__
is even worse though: Maybe I want a full path with the filename and maybe I
don't. So, I don't use the __FILE__ macro either. I do use the __LINE__
macro though (not much to go wrong with that!). I wonder if it is
implementation defined what __FILE__ and __func__ include (?). Finally, as a
minor peeve: why are the specifiers not both consistent in case (__FILE__ &
__FUNC__ or __file__ & __func__)?

Tony
 
T

Tony

Nick Keighley said:
On 19 Nov, 13:11, arnuld <[email protected]> wrote:
basically you have to check the return value of every function.

Which would be a very acceptable strategy for a large class of errors if C
had a return value type that "exploded" (C++ term) if it wasn't checked.
Then, the "return an error indicator" strategy becomes robust and not "error
prone" as so many C++ afficionados continually harp as a major justification
for exception handling.

Note that many functions do not generate errors and can have a void return.
It is worth trying to make as many functions as possible void return
functions. Many more functions could be void return functions if C had
pass-by-reference arguments (null ptr checks need not be done within the
function as a precondition check then).

So, I'm suggesting those 2 things (exploding error return val and
pass-by-reference) be introduced into C. :)

Tony
 
T

Tony

Ben Bacarisse said:
Do you mean something that simply reports errors? If so a starting
point might be (uses C99):

#define REPORT(...) do { \
fprintf(stderr, "In %s(): ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)

Don't you just adore variadic macros? :)

Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,237
Latest member
AvivMNS

Latest Threads

Top