Ch20.2 – Signal Generation & Delivery

 

Ch20.2 – Signal Generation & Delivery
Linux System Programming Β· EmbeddedPathashala
πŸ“‘ Topic 2 of 19
🎯 Beginner–Intermediate
πŸ’» 2 Code Examples
❓ Interview Q&A
πŸ”‘ Key Terms
Signal Generation Signal Delivery Asynchronous Delivery Synchronous Delivery Hardware Exception Terminal Characters Software Event Standard Signals Realtime Signals
Generation vs Delivery β€” What’s the Difference?

Generation is the moment an event happens that creates the signal. Delivery is when the kernel actually hands that signal to the target process and the process reacts to it.

These two steps are separate. Between generation and delivery, the signal sits in a pending state. This gap matters because the process might be blocked, sleeping, or currently masking (blocking) that particular signal.

⚑ Three Causes of Signal Generation
Cause Category Concrete Example Signal Raised
Hardware Exception Program divides an integer by zero; CPU detects fault, notifies kernel SIGFPE
Hardware Exception Program dereferences a NULL pointer (invalid memory access) SIGSEGV
Hardware Exception Program executes a malformed machine instruction SIGILL
Terminal Special Key User presses Ctrl+C at the keyboard SIGINT
Terminal Special Key User presses Ctrl+Z at the keyboard SIGTSTP (stop)
Software Event A timer set with alarm() expires SIGALRM
Software Event A child process exits SIGCHLD
Software Event Process exceeds its CPU time limit SIGXCPU

πŸ”€ Asynchronous vs Synchronous Delivery

Most signals are delivered asynchronously β€” you cannot predict which instruction is executing when the signal arrives. For example, SIGALRM from a timer fires at wall-clock time, not at a particular line of code.

Some signals are synchronous β€” they are always triggered by a specific instruction in the program and delivered immediately. Hardware exceptions fall here: SIGSEGV always happens at the exact instruction that touches bad memory.

Type Predictable? Example
Asynchronous No – arrives at any time SIGALRM, SIGINT, SIGCHLD
Synchronous Yes – tied to an instruction SIGSEGV, SIGFPE, SIGILL

πŸ“Š Standard Signals vs Realtime Signals

Linux has two families of signals:

Feature Standard Signals (1–31) Realtime Signals (32–64)
Queued? No – only one pending at a time Yes – multiple instances queue up
Order guaranteed? No Yes – delivered lowest number first
Defined in <signal.h> as SIGxxx names SIGRTMIN to SIGRTMAX
This chapter covers Yes Described in Section 22.8
Key point: Standard signals are not queued. If SIGUSR1 is sent 1000 times while blocked, the process receives it only once when unblocked. Realtime signals queue all instances.

πŸ’» Code Example 1 – Trigger a Synchronous Signal (SIGSEGV)

This demonstrates synchronous generation: dereferencing a NULL pointer always causes SIGSEGV at that exact instruction. The kernel delivers it immediately without any scheduling delay.

/* Example: Trigger SIGSEGV (synchronous signal)
   Compile: gcc -o sigsegv_demo sigsegv_demo.c
   Run:     ./sigsegv_demo
   Expected output: Segmentation fault (core dumped) */

#include <stdio.h>

int main(void)
{
    int *ptr = NULL;   /* null pointer */

    printf("About to dereference a NULL pointer...\n");
    printf("This will trigger SIGSEGV (synchronous).\n");

    *ptr = 42;  /* BAD: write to address 0 β†’ SIGSEGV generated HERE */

    /* The line below will never execute */
    printf("This line is never reached.\n");

    return 0;
}
Expected: “Segmentation fault (core dumped)”. The kernel detected invalid memory access at the *ptr = 42 instruction and delivered SIGSEGV synchronously.

πŸ’» Code Example 2 – Trigger an Asynchronous Signal (SIGALRM)

SIGALRM is asynchronous β€” the kernel delivers it when a real-time timer expires, regardless of what instruction is currently running. Here we use alarm() to schedule it after 3 seconds.

/* Example: Asynchronous SIGALRM after 3 seconds
   Compile: gcc -o alrm_demo alrm_demo.c
   Run:     ./alrm_demo
   Expected: alarm fires after 3s and terminates the process */

#include <stdio.h>
#include <unistd.h>  /* alarm(), sleep() */

int main(void)
{
    printf("Setting alarm for 3 seconds...\n");
    alarm(3);   /* ask kernel to send SIGALRM after 3 seconds */

    /* The loop below will be interrupted asynchronously */
    int i = 0;
    while (1) {
        printf("Working... i = %d\n", i++);
        sleep(1);
    }

    /* Process will be killed by SIGALRM before reaching here */
    return 0;
}
Output: You’ll see “Working… i=0”, “Working… i=1”, “Working… i=2”, then the process terminates with “Alarm clock” message. The signal arrived asynchronously after 3 seconds.

❓ Interview Questions
Q1. What is the difference between signal generation and signal delivery?
Generation is when the triggering event occurs and the kernel creates the signal internally. Delivery is when the kernel actually acts on it by calling the process’s handler or applying the default action. Between the two, the signal is “pending.”
Q2. Give two examples of synchronous signals and explain why they are synchronous.
SIGSEGV (invalid memory access) and SIGFPE (arithmetic error). They are synchronous because they are caused directly by a specific instruction in the program. The signal is always generated at that instruction and delivered immediately.
Q3. What are the three categories of events that cause the kernel to generate a signal?
1. Hardware exceptions (divide-by-zero, bad memory access, illegal instruction). 2. Terminal special characters (Ctrl+C, Ctrl+Z, Ctrl+\). 3. Software events (timer expiry, child termination, I/O availability, CPU limit exceeded).
Q4. What is the key difference between standard signals and realtime signals?
Standard signals (1–31) are not queued β€” if the same signal is sent multiple times while blocked, only one instance is delivered. Realtime signals (SIGRTMIN to SIGRTMAX) are queued β€” all instances are delivered in order.
Q5. Can a process receive a signal while it is sleeping (in a sleep() call)?
Yes. sleep() can be interrupted by a signal. When a signal is delivered to a sleeping process, the process wakes up, handles the signal, and if the handler returns, sleep() returns early with the number of seconds remaining.
Q6. What happens to a pending standard signal if the same signal is sent again before it is delivered?
The second instance is silently discarded. Standard signals use a single pending bit per signal β€” not a queue. So no matter how many times the signal is sent while pending, only one delivery occurs.
Next Topic β†’

Pending Signals – What does “pending” really mean and how does it work?

Next: Pending Signals β†’ ← Previous

Leave a Reply

Your email address will not be published. Required fields are marked *