arrow left
Back to Developer Education

Signal Handling In C++

Signal Handling In C++

There are interruptions that come up in your program, which are delivered to a process that runs on an operating system and pauses the running process. These interruptions are called signals. An example signal can be generated by pressing Ctrl+C on various operating systems (Windows, Mac OS X, LINUX, or UNIX). <!--more--> The key combination sends an interrupt signal on most cases. Before we go into signal handling in C++, you may want to know a little about the programming language.

What is the C++ programming language?

C++ is a general-purpose cross-platform programming computer language, which is case-sensitive and free-form. The language is highly flexible and scalable and gives programmers an optimized level of control over system memory and resources.

It is used for the development of operating systems (OS), browsers, apps, games, software, graphical user interfaces (GUIs), etc. The imperative and compiled language is a powerful framework that supports different methods of programming such as object-oriented paradigm, functional programming, generic programming, and procedural programming.

Signal handling in C++

We now understand that signals are interruptions that stop an OS in its task to attend to another task, and to stop these tasks, the signals need to be handled. In C++, signals are provided by the language.

It catches the interrupting signal and solves the problem that causes the program to pause while executing its task. Below is the C++ signal library, signals that a developer can work with and their operations.

Signal operations

  1. SIGINT (signal interrupt) - This signal is used to generate an interactive attention signal as a "program interrupt" at the receiver end. When the OS generates an interrupt, this C++ signal halts the interrupt and allows the ongoing task to continue.

  2. SIGTERM (signal termination) - This signal is generated by the kill command and is used to send a request to the running program for the termination of the incoming interrupt. The incoming signal is killed before it arrives to interrupt the ongoing execution of a task.

  3. SIGBUS (signal bus) - When there is an indication of BUS error, it means there is access to an invalid address. This signal notifies the ongoing program that there is a BUS error gaining access to an invalid address and the program is stopped.

  4. SIGILL (signal illegal instruction) - This signal is used to detect an illegal command or instruction, which could be the interrupt and puts a stop to it.

  5. SIGALRM (signal alarm) - This signal uses the alarm function to indicate access to an invalid address (interrupt) by showing the expiration of time.

  6. SIGSEGV (signal segmentation violation) - The signal shows and handles interrupts as storage with invalid access.

  7. SIGHUP (signal hang up) - This signal is used to report to a process that its controlling terminal has been terminated by an interrupt.

  8. SIGQUIT (signal quit) - This signal produces a core dump which is used to terminate the interrupt on its generation.

  9. SIGTRAP (signal trap) - This signal is used to trace all traps (or exceptions) and sends information to the ongoing process about them, requesting termination.

  10. SIGCONT (signal continue) - This signal is sent to the ongoing process to make it continue after an interrupt has been blocked or terminated.

  11. SIGSTOP (signal stop) - This signal automatically terminates and blocks any interrupt that threatens to come up in a process.

The signals listed above can trap any interrupt (or exception) and resolve the problems.

C++ Signal() function

How C++ signal() functions work

The C++ signal() functions follow a string of processes that works to bring the desired solution. The first thing to note is that there are two arguments represented in all signal functions and both play a vital role.

signal(registered signal, signal handler);

The first argument, which is the registered signal and integer, gets involved with the signal method and the second parameter, the signal handler works on catching all interrupts and exceptions through the C++ signals.

When the signal functions are compiled, they will generate an output. This output will be needed to create a visibly different interruption, meaning the signal used when catching interrupts would print them.

Following the process, another function called the raise function is included. This function considers the first argument and sends defined signals to the currently executing program. Raising a function generates the necessary signal.

Signal functions to note in the process include:

Prototypes

This signal function is defined in a <csignal> header file and describes a method of signal handling.

Through the function, the handler can be set to perform one of the following actions:

  • Handling a signal by default.
  • Handling the signal by ignoring it.
  • Handling the signal by a user-defined function.

Parameters

This signal function is comprised of sig and handler. sig is the signal that the signal handler handles.

It can be either of the signals mentioned in the list below:

  • Signal Abort (SIGABRT)
  • Signal Floating-Point Exception (SIGFPE)
  • Signal Illegal Instruction (SIGILL)
  • Signal Interrupt (SIGINT)
  • Signal Termination (SIGTERM), etc

The signal should be in the form: void fun(int sig);

Return value

This is the value that returns when the request of the function inputted is successful or not. If successful, it returns to the particular signal handler that was in charge of the command. But if it is not successful, SIG_ERR is returned.

Implementation

The compilation below illustrates the implementation of a signal handling process when the SIGSEGV method is used.

#include <csignal>   
#include <iostream>   
using namespace std;   
    
sig_atomic_t sig_value = 0;   
void s_handle(int signal_)   
{   
    sig_value = signal_;   
}   
    
int main()   
{   
    signal(SIGSEGV, s_handle);   
    cout << "Before the signal handler has been invoked " << sig_value << endl;   
    raise(SIGSEGV);   
    cout << "After the signal handler has been invoked  " << sig_value << endl;   
    return 0;
}

Once compiled and executed, the return value will indicate the following result:

Before the signal handler has been invoked 0
After the signal handler has been invoked 11

Conclusion

In this article we learned how to handle signals in C++ programming language. We looked at signals operations and how they are implemented.

Happy coding!

Further reading

You can learn more about other signal concepts by visiting this page:

Signal Handling ::signal() function - cppsecrets.com


Peer Review Contributions by: Geoffrey Mungai

Published on: Dec 28, 2021
Updated on: Jul 15, 2024
CTA

Start your journey with Cloudzilla

With Cloudzilla, apps freely roam across a global cloud with unbeatable simplicity and cost efficiency