主要内容

CERT C: Rec. ERR06-C

Understand the termination behavior of assert() and abort()

Since R2026a

Description

Understand the termination behavior of assert() and abort()1

Polyspace Implementation

The rule checker checks forAbnormal termination of program that uses atexit().

Examples

expand all

Issue

The rule checker reports a violation if you use the assert() macro or invoke the abort() function after registering a function with atexit().

Risk

Functions registered with atexit() are invoked only when the program terminates normally via the exit() function. These functions are not invoked if the program terminates abnormally via the abort() function. If these functions perform critical tasks such as memory management, those tasks are not executed, leading to potential resource leaks and unpredictable behavior.

Fix

Avoid calling the abort() function. Check for error condition and if necessary, terminate the program by calling the exit() function.

If you use C11 or later, replace the run-time assert() by using static_assert(). Static assertions are checked during compile time and does not modify the run-time behavior of the code.

Example

In this code, an assertion is made after registering the cleanup function cleanup() with atexit(). If the assertion fails, then the cleanup function is not invoked, leading to a memory leak.

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

// Global pointer to store the allocated memory for the string
char *globalString = NULL;

// Cleanup function to free the allocated memory
void cleanup(void) {
    if (globalString != NULL) {
        printf("Cleaning up allocated memory...\n");
        free(globalString);
        globalString = NULL;
    }
}

// Function to allocate memory for a string
void allocateString(void) {
    // Allocate memory for the string
    globalString = (char *)malloc(50 * sizeof(char));  // Allocate 50 bytes
    if (globalString == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }

    // Copy a string into the allocated memory
    strcpy(globalString, "Dynamically allocated string");

    // Register the cleanup function
    if (atexit(cleanup) != 0) {
        fprintf(stderr, "Failed to register cleanup function\n");
        exit(EXIT_FAILURE);
    }

    // Assert that globalString is not NULL
    assert(globalString != NULL);   //Noncompliant
}

Correction

To fix this violation, replace the assert() statement with an if statement that calls the exit() function if there is an error.

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

// Global pointer to store the allocated memory for the string
char *globalString = NULL;

// Cleanup function to free the allocated memory
void cleanup(void) {
    if (globalString != NULL) {
        printf("Cleaning up allocated memory...\n");
        free(globalString);
        globalString = NULL;
    }
}

// Function to allocate memory for a string
void allocateString(void) {
    // Allocate memory for the string
    globalString = (char *)malloc(50 * sizeof(char));  // Allocate 50 bytes
    if (globalString == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }

    // Copy a string into the allocated memory
    strcpy(globalString, "Dynamically allocated string");

    // Register the cleanup function
    if (atexit(cleanup) != 0) {
        fprintf(stderr, "Failed to register cleanup function\n");
        exit(EXIT_FAILURE);
    }

    // Check that globalString is not NULL
    if(globalString != NULL){   //Compliant
        exit(EXIT_FAILURE);
    }
}

Check Information

Group: Rec. 12. Error Handling (ERR)
PQL Name: std.cert.ERR06_C

Version History

Introduced in R2026a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.