Main Content

CERT C++: MSC54-CPP

A signal handler must be a plain old function

Since R2023b

Description

Rule Definition

A signal handler must be a plain old function.1

Polyspace Implementation

The rule checker checks for the issue Signal handler not signal safe.

Examples

expand all

Issue

This issue occurs when you use a signal handler that is not signal safe. For C++14 and earlier, a signal-safe function is a plain old function (POF). A POF is a function that uses only the features of C++ that is common to both C and C++ and has C linkage. For C++17 and later, the definition of a signal-safe function is relaxed slightly. See MSC54-CPP.

Risk

If a signal handler is not signal safe, its behavior can be undefined or implementation defined. For instance, if your signal handler function implements exception handling, its behavior is generally undefined.

Fix

To fix this violation, use signal-safe functions as signal handlers. To avoid using unsafe functions as signal handlers, you might need to refactor your code.

Example — Use of static Function as Signal Handler

In this example, the function installSignalHandler() installs the static function mySignalHandler as a signal handler. Because the function mySignalHandler has static linkage instead of "C" linkage, using this function as a signal handler violates this rule. Polyspace® reports a violation for the definition of the function mySignalHandler.

#include <csignal>

static void mySignalHandler(int flag) { //Noncompliant
	// Implementation details elided.
}

void installSignalHandler() {
	if(SIG_ERR == std::signal(SIGTERM, mySignalHandler)) {
		// Handle error
	}
}
Correction — Use Functions with "C" linkage

To fix this issue, use a function with "C" linkage as the signal handler.

#include <csignal>
extern "C" void CSignalHandler(int flag) { //Compliant
	// Implementation  ...
}

void installSignalHandler() {
	if(SIG_ERR == std::signal(SIGTERM, CSignalHandler)) {
		// Handle error
	}
}
Example — Use of Exception Handling Functions as Signal Handler

In this example, the function installSignalHandler() installs the noexcept function mySignalHandler as a signal handler. The function mySignalHandler does not throw any exceptions, but uses exception handling code that is not supported in C. This function is not signal safe and Polyspace reports a violation.

#include <csignal>

void mySignalHandler(int flag) noexcept(true) { //Noncompliant
	// Perform task that can throw exception
	try {
		//...
	} catch(...) {
		//...
	}
}

void installSignalHandler() {
	if(SIG_ERR == std::signal(SIGTERM, mySignalHandler)) {
		// Handle error
	}
}
Correction — Refactor Code to Make Signal Handler Signal Safe

To fix this defect, remove the exception handling code from the signal handler completely. For instance, use the signal handler to set a flag. Then, poll the flag in a separate function that handles the exception handling code.

#include <csignal>
volatile sig_atomic_t FLAG = 0;
extern "C" void mySignalHandler(int flag) {
	//set FLAG
	FLAG = 1;
}

void installSignalHandler() {
	if(SIG_ERR == std::signal(SIGTERM, mySignalHandler)) {
		// Handle error
	}
}

void poll() {
	if(FLAG == 1) {
		//reset the FLAG
		FLAG = 0;
		// Perform task that can throw exception
		try {
			//...
		} catch(...) {
			//...
		}
	}

}

Check Information

Group: 49. Miscellaneous (MSC)

Version History

Introduced in R2023b


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.