Debugging Tools - aryanjoshi0823/5143-Operating-System GitHub Wiki

Debugging tools like strace, gbd

1. strace (System Call Tracer)

How It Works:

  1. Intercepting System Calls:

    • Programs communicate with the operating system kernel through system calls (e.g., file I/O, memory allocation, networking).
    • strace uses a mechanism called ptrace (process trace) provided by the Linux kernel to intercept and monitor these system calls made by a program.
    • When a program makes a system call, it switches from user mode to kernel mode. During this transition, strace hooks into the process to log the call, its arguments, and the result.
  2. Attaching to a Process:

    • strace can attach to a running process (using its PID) or start a program from scratch.
    • When attached, it tracks all system calls the process invokes until it exits or detaches.
  3. Tracking System Calls:

    • strace monitors all system calls made by the program, including:
      • File operations (open, read, write, close).
      • Memory management (mmap, brk).
      • Process control (fork, execve).
      • Networking (socket, connect).
    • It logs these calls in a human-readable format, displaying the call name, arguments, and return values.
  4. Filtering:

    • strace allows users to filter system calls for specific areas of interest. For example:
      • To trace only file-related calls: strace -e file ./myprogram.
  5. Signals Handling:

    • In addition to system calls, strace logs signals received by the program, such as SIGSEGV (segmentation fault) or SIGINT (interrupt signal).

Practical Workflow:

  • The kernel handles system calls via interrupts, and strace intercepts these interrupts.
  • Each intercepted system call is analyzed and formatted by strace before displaying it to the user.
  • Example Output:
    open("example.txt", O_RDONLY) = 3
    read(3, "Hello, World!", 13) = 13
    close(3) = 0
    

How Developers Use It:

  • Diagnose resource issues (e.g., why a file cannot be opened).
  • Debug permission problems by analyzing open and stat calls.
  • Analyze runtime behavior when source code is unavailable.

2. gdb (GNU Debugger)

How It Works:

  1. Debugging Symbols:

    • Programs must include debugging symbols (via the -g flag during compilation) to provide detailed insights into variables, function names, and line numbers.
    • Without these symbols, gdb can only analyze raw assembly code, which makes debugging much harder.
  2. Controlling Program Execution:

    • gdb allows fine-grained control over a program’s execution.
    • It starts the program inside a controlled environment where:
      • Users can pause execution (breakpoints).
      • Step through code line by line.
      • Modify the program state.
  3. Breakpoints:

    • A breakpoint is a marker set at a specific line or function.
    • When the program reaches this point, it halts execution and gives control to gdb.
    • Example:
      • break main: Stops execution at the beginning of the main function.
  4. Inspecting Program State:

    • While halted, developers can:
      • Inspect variables: Check the value of local and global variables.
      • View memory: Examine specific memory addresses.
      • Backtrace: Analyze the call stack to see the sequence of function calls leading to the current state.
  5. Step-by-Step Execution:

    • Developers can execute the program step-by-step to identify where the bug occurs:
      • step: Executes the next line of code, entering into function calls.
      • next: Executes the next line of code but skips over function calls.
  6. Signal Handling:

    • gdb can intercept signals like SIGSEGV (segmentation faults) and pause execution at the fault point.
    • This is crucial for diagnosing memory errors such as accessing invalid memory locations.
  7. Core Dump Analysis:

    • When a program crashes and generates a core dump (a snapshot of the program's memory at the time of the crash), gdb can analyze it to pinpoint the issue:
      • gdb ./myprogram core
  8. Dynamic Program Modification:

    • gdb allows developers to modify variable values during execution to test how the program reacts to different inputs.

Practical Workflow:

  • gdb injects itself between the program and the CPU to manage instructions.
  • It uses debugging symbols to map machine-level instructions to source code lines.
  • Example Workflow:
    • Compile the program: gcc -g -o myprogram myprogram.c.
    • Start debugging: gdb ./myprogram.
    • Set a breakpoint: break main.
    • Run the program: run.
    • Inspect a variable: print variable_name.

Key Differences in Functionality

Feature strace gdb
Focus Monitors system calls and signals. Debugs program logic and source code.
Setup Works directly on binaries. Requires source code with debug symbols.
Level of Analysis System-level behavior (e.g., syscalls). Application-level behavior (e.g., code).
Control Observes only; no execution control. Full control over program execution.
⚠️ **GitHub.com Fallback** ⚠️