Skip to content

SinhaWiz/SIGNAL

Repository files navigation

Signal

POSIX-compliant signal handling subsystem for mCertikos

Highlights

  • Asynchronous process notification via 32 signal types
  • Custom signal handlers with safe context save/restore
  • Kernel-injected trampoline for automatic sigreturn
  • Full SIGKILL/SIGINT/SIGFPE support
  • Hardware exception isolation (division by zero recovery)

Overview

Signal provides a mechanism for the kernel to interrupt user processes and notify them of events. Processes can register custom handlers, block signals, or rely on default actions. The implementation follows POSIX semantics and integrates with mCertikos trap handling.

Table of Contents

Installation

make
make qemu

Quick Start

Register a handler and send a signal:

#include <signal.h>

void handler(int sig) {
    printf("Caught signal %d\n", sig);
}

int main() {
    struct sigaction sa = { .sa_handler = handler };
    sigaction(SIGUSR1, &sa, NULL);
    pause();  // Wait for signal
    return 0;
}

From shell:

kill 10 <pid>   # Send SIGUSR1
kill 9 <pid>    # Terminate process

Architecture

+-------------+    signal    +-------------+    trap     +-------------+
|   Process   | <----------- |   Kernel    | <---------- |  Hardware   |
+-------------+              +-------------+             +-------------+
      |                            |
      | handler()                  | pending_signals |= (1 << sig)
      v                            |
+-------------+              +-------------+
| Trampoline  | -----------> | sigreturn   |
+-------------+   int 0x30   +-------------+

Workflow

  1. Event triggers signal (keyboard, exception, kill())
  2. Kernel sets pending bit in target TCB
  3. On trap return, kernel checks pending signals
  4. Kernel saves context, sets up stack frame, redirects to handler
  5. Handler executes and returns
  6. Trampoline invokes sys_sigreturn
  7. Kernel restores context, process resumes

API Reference

System Calls

Call Description
sigaction(sig, act, oldact) Register handler
kill(pid, sig) Send signal
pause() Block until signal
sigreturn() Restore context (internal)

Data Structures

struct sigaction {
    sighandler_t sa_handler;
    uint32_t     sa_mask;
    int          sa_flags;
    void         (*sa_restorer)(void);
};

struct sig_state {
    struct sigaction sigactions[NSIG];
    uint32_t         pending_signals;
    int              signal_block_mask;
};

Trampoline

The trampoline is a 7-byte stub injected onto the user stack. It ensures handlers return to kernel via sigreturn.

Purpose

  • Automatic context restoration after handler
  • POSIX compliance without user cooperation
  • Safe return path from any handler

Implementation

movl $29, %eax    ; SYS_sigreturn
int  $0x30        ; trap to kernel
uint8_t trampoline[7] = {
    0xB8, 0x1D, 0x00, 0x00, 0x00,  // mov $29, %eax
    0xCD, 0x30                     // int $0x30
};

Stack Setup

uint32_t sp = tf->esp;
sp -= 7;
memcpy((void*)sp, trampoline, 7);
uint32_t ret_addr = sp;

sp -= 4; *(uint32_t*)sp = ret_addr;  // return address
sp -= 4; *(uint32_t*)sp = signum;    // argument

tf->esp = sp;
tf->eip = (uint32_t)handler;

sigreturn

  1. Kernel receives syscall 29
  2. Retrieves saved context from TCB
  3. Restores EIP, ESP, registers
  4. Clears handler flag
  5. Returns to interrupted code

sys_kill Flow

int sys_kill(int pid, int signum) {
    if (signum < 1 || signum >= NSIG) return -1;
    if (pid <= 0) return -1;
    
    struct TCB *target = tcb_get(pid);
    if (!target || target->state == TSTATE_DEAD) return -1;
    
    if (signum == SIGKILL) {
        target->state = TSTATE_DEAD;
        thread_remove_from_queue(pid);
        return 0;
    }
    
    target->sigstate.pending_signals |= (1 << signum);
    
    if (target->state == TSTATE_SLEEP) {
        target->state = TSTATE_READY;
        thread_add_to_queue(pid);
    }
    
    return 0;
}
kill(pid, sig)
     |
     v
  Validate -----> Error
     |
     v
  SIGKILL? --yes--> Terminate
     |
     no
     v
  Set pending
     |
     v
  Wake if sleeping
     |
     v
  return 0

Signal Reference

Signal Num Action Catchable
SIGHUP 1 Term Yes
SIGINT 2 Term Yes
SIGQUIT 3 Term Yes
SIGILL 4 Term Yes
SIGFPE 8 Term Yes
SIGKILL 9 Term No
SIGUSR1 10 Term Yes
SIGSEGV 11 Term Yes
SIGUSR2 12 Term Yes
SIGTERM 15 Term Yes
SIGCHLD 17 Ign Yes
SIGSTOP 19 Stop No

Files

kern/
  lib/signal.h              # Signal definitions
  trap/TSyscall/TSyscall.c  # Syscall implementations
  trap/TDispatch/TDispatch.c
  trap/TTrapHandler/TTrapHandler.c
  thread/PTCBIntro/PTCBIntro.c

user/
  include/signal.h          # User interface
  lib/signal.c              # Library wrappers

Testing

+-----------+                      +-----------+
|  Parent   |  -- kill(child) -->  |   Child   |
|           |                      |  handler  |
|           |  <-- kill(parent) -- |           |
|  handler  |                      |           |
+-----------+                      +-----------+
      |                                  |
      +------ trampoline/sigreturn ------+
      |                                  |
      v                                  v
   resume                             resume

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors