You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

The C99 exit() function is used for normal program termination. If more than one call to exit() is executed by a program, the behavior is undefined. This may occur when functions are registered with atexit(), a function that causes the functions registered to it to be called with when the program exits. If a function called as a result of being registered with atexit() has an exit() call in it there is undefined behavior.

Non-Compliant Code Example

In this code as the main function exits two functions registered with atexit() are called. Given the define statement exitearly=1 the program calls exit within the first function called in the atexit() cycle. The behavior that follows is undefined: some implementations will ignore the second call to exit and just continue calling the atexit functions in the appropriate order. Other implementations will enter an infinite loop with the atexit functions being called repeatedly.

#include <stdio.h>
#include <stdlib.h>

#define exitearly 1

void exit1(void) {
  puts("Exit second.\n");
}

void exit2(void) {
  puts("Exit first.\n");
  if (exitearly) {
     exit(1);
  }
}

int main (void) {

  if (expr) {
    atexit(exit1);
    atexit(exit2);
    exit(1);
  }
  else {
    exit2();
  }

  return 0;
}

Compliant Code

To have functionality where the program can quit from within a function registered by at_exit() it is necessary to use a function used for abnormal termination such as _Exit() or abort().

<include _Exit() description>

#include <stdio.h>
#include <stdlib.h>

#define exitearly 1

void exit1(void)
{
  printf("Exit second.\n");
}

void exit2 (void)
{
  printf("Exit first.\n");
  if (exitearly) {
     _Exit(1);
  }
}

int main (void) {

  if (expr) {
    atexit(exit1);
    atexit(exit2);
    exit(1);
  }
  else {
    exit2();
  }

  return 0;
}

All functions registered by the atexit() function are called, in the reverse order of their registration.

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC31-C

1 (low)

1 (unlikely)

3(low)

P6

L2

References

[[ISO/IEC 9899-1999]] Section 7.20.4.3, "The exit function"

  • No labels