Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C programming error handling

I want my code to be able to handle the error cases, such as unsuccessful return of functions. For instance,pthread_create,normally I use the function herebelow:

int thread_check1;
 pthread_t function;
 thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
if(thread_check1 != 0){
   fprintf(stderr, "pthread_create error\n");
   exit(1);
}

Considering the error cases, would it be correct to call the same function till it returns 0(for this specific function) as it is done below?

thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}

Can I apply the same logic to the other C functions that returns a value? Otherwise, how would you suggest to handle error cases (for the function returns) without exiting from the program?

like image 600
sven Avatar asked Jan 04 '13 16:01

sven


People also ask

What is C error handling?

The C programming language does not support exception handling nor error handling. It is an additional feature offered by C. In spite of the absence of this feature, there are certain ways to implement error handling in C. Generally, in case of an error, most of the functions either return a null value or -1.

Does C have error handling?

C does not provide direct support for error handling (also known as exception handling). By convention, the programmer is expected to prevent errors from occurring in the first place, and test return values from functions.

How do you handle errors in programming?

A function can throw exceptions or can choose to handle exceptions. Error handling code can also be separated from normal code with the use of try blocks, which is code that is enclosed in curly braces or brackets that could cause an exception. Try blocks can help programmers to categorize exception objects.


2 Answers

You could do that, but more properly. Assume there is function f which has different return values. You can do as follows:

tries_left = 1000;
do
{
    ret = f(params);
    if (ret == OK)
        break;
    else if (ret == SOMETHING_UNRECOVERABLE)
        /* break with failure */
    else if (ret == SOMETHING_FIXABLE)
        /* fix params */
    else
        /* sleep a little */
} while (--tries_left);

There are many things to consider here:

  • Avoid infinite loop. If there is something inherently wrong, you wouldn't want to get stuck in a loop. So after some tries, you would want to break and fail. This is where tries_left comes into play.
  • Fail if unrecoverable. If the error tells you that the problem is not fixable, stop trying. For example if you are trying to mount a drive and it tells you /dev/sda6 doesn't exist, there is no point in retrying.
  • Try actually handling the problem. In some cases, you may be able to try different parameters. For example if you are trying to create a backup file and you can't, you can try changing the directory or name of the file and try again.
  • Don't use 100% CPU. If you want to retry, at least give some breathing room in between tries for whatever problem there was to go away, or in the very least to avoid using maximum CPU.

In the end, to avoid repeating yourself if you have different functions that need to be handled like this, you could put this whole thing in a macro and call it like CHECK_AND_RETRY(f(params));, assuming it is possible to understand what return value is unrecoverable and what is fixable no matter the function (kind of restrict, but there is no beautiful solution).

like image 193
Shahbaz Avatar answered Sep 28 '22 07:09

Shahbaz


As Joe already mentions it heavily depends on your requirements and on the method you want to use. Whenever something fails there's usually a reason. For example no more memory is available if malloc returns zero.

Trying to get new memory without actually using free under such circumstances will usually result in an infinite loop, so that's something you shouldn't do. On the other hand, when you want to open a file but it's currently blocked by another process you could do something similar.

However, keep in mind that such a loop will usually keep the CPU busy and slow down other processes/threads. Also you could use a thing between your current solutions and try several times before you exit:

error_count = 0;
thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    sleep(1); // wait some time before we try again
    if(++error_count == 10){
        fprintf(stderr, "Could not create thread\n");
        return 1;
    }
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}
like image 27
Zeta Avatar answered Sep 28 '22 07:09

Zeta