Calling the signal()
function in a multithreaded program is undefined behavior according to C11 (Section 7.14.1.1, paragraph 7).
This rule is a specific instance of SIG02-C. Avoid using signals to implement normal functionality.
Noncompliant Code Example
This code raises a signal within a child thread. This is meant to terminate the program, but results in undefined behavior.
void func(void *data) { /* ... */ if (thread_should_exit) { raise( SIGTERM); // Undefined! } /* ... */ } int main(void) { int result; thrd_t thread; int result; if ((result = thrd_create(&tid, func, NULL)) != thrd_success) { /* Handle Error */ } return 0; }
Compliant Solution
This code terminates the child thread rather than raising a signal. This has the same effect as the noncompliant code example, but is well-defined in C11.
void func(void *data) { /* ... */ if (thread_should_exit) { thrd_exit(0); // OK } /* ... */ } int main(void) { int result; thrd_t thread; int result; if ((result = thrd_create(&tid, func, NULL)) != thrd_success) { /* Handle Error */ } return 0; }
Exceptions
CON37:EX0: Platforms that provide defined behavior when multithreaded programs use custom signal handlers are exempt from this rule. This would include POSIX, for example.
Risk Assessment
Mixing signals and threads causes undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON37-C | low | probable | low | P6 | L2 |