Skip to content

Instantly share code, notes, and snippets.

@arpit-saxena
Last active December 30, 2025 11:10
Show Gist options
  • Select an option

  • Save arpit-saxena/abe368ca5190c30ebd1dc0a08b3ab6cb to your computer and use it in GitHub Desktop.

Select an option

Save arpit-saxena/abe368ca5190c30ebd1dc0a08b3ab6cb to your computer and use it in GitHub Desktop.
Demonstrate two signal handling mechanisms for testing with gdb

signal_handling.c demonstrates 2 (of many) methods of handling signals in Linux: signalfd and signal(). We want to demonstrate that these 2 work differently with GDB.

Compile the program with -g flag then run under GDB. To run with signalfd:

(gdb) r signalfd

Try pressing Ctrl+C. This will stop GDB and also terminate the program as it receives a SIGINT.

To run using signal function:

(gdb) r signal

Now try pressing Ctrl+C. This SIGINT is intercepted by GDB and leads to the GDB prompt with the program being paused. You can continue it again at this time.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/signalfd.h>
/* Signal handler for traditional signal() approach */
static void sigint_handler(int signo)
{
printf("\nReceived SIGINT (signal %d)\n", signo);
printf("Exiting gracefully...\n");
_exit(EXIT_SUCCESS);
}
static void use_signalfd(void)
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
/* Block SIGINT so it won't be handled by the default signal handler */
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
perror("sigprocmask");
exit(EXIT_FAILURE);
}
/* Create a signalfd for SIGINT */
sfd = signalfd(-1, &mask, 0);
if (sfd == -1) {
perror("signalfd");
exit(EXIT_FAILURE);
}
printf("Using signalfd mode. Waiting for SIGINT (press Ctrl+C)...\n");
/* Read from signalfd - this blocks until a signal arrives */
s = read(sfd, &fdsi, sizeof(fdsi));
if (s != sizeof(fdsi)) {
perror("read");
exit(EXIT_FAILURE);
}
/* Handle the signal */
if (fdsi.ssi_signo == SIGINT) {
printf("\nReceived SIGINT (signal %d)\n", fdsi.ssi_signo);
printf("Sent by PID: %d, UID: %d\n", fdsi.ssi_pid, fdsi.ssi_uid);
printf("Exiting gracefully...\n");
}
close(sfd);
}
static void use_signal(void)
{
/* Register the signal handler */
if (signal(SIGINT, sigint_handler) == SIG_ERR) {
perror("signal");
exit(EXIT_FAILURE);
}
printf("Using signal mode. Waiting for SIGINT (press Ctrl+C)...\n");
/* Wait indefinitely for the signal */
while (1) {
pause();
}
}
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <signalfd|signal>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (strcmp(argv[1], "signalfd") == 0) {
use_signalfd();
} else if (strcmp(argv[1], "signal") == 0) {
use_signal();
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[1]);
fprintf(stderr, "Usage: %s <signalfd|signal>\n", argv[0]);
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment