Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trutisui

Linux Glibc

A small dynamic memory fault injector for glibc linux systems written in C11.

It intercepts memory allocations (malloc, calloc, realloc, posix_memalign, aligned_alloc) at runtime via LD_PRELOAD. This allows you to deterministically simulate Out-Of-Memory (OOM) conditions to test how your application handles memory failures w/o modifying/recompiling any source code.

This is made as an experimental learning project and may be very unstable.

Requirements

  • Linux 2.6+
  • glibc 2.30+
  • GCC 4.9+ or Clang 3.6+
  • CMake 3.20+

Building

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

This produces the shared library at build/libtrutisui.so.

Usage

Inject Trutisui shared library into any dynamically linked executable using the LD_PRELOAD env var.

1. Start Failing Immediately (Default)

Trutisui will start failing from the very first memory allocation.

LD_PRELOAD=/path/to/trutisui/build/libtrutisui.so ./my_app

2. Start Failing After N Allocations

Control exactly when the fault start occuring using the TRUTISUI_FAIL_AFTER env var. Useful when an app needs to run some startup code.

# Force my_app to start failing on its 100th memory allocation
TRUTISUI_FAIL_AFTER=100 LD_PRELOAD=/path/to/trutisui/build/libtrutisui.so ./my_app

Understanding the Output

When Trutisui injects a fault, it logs a single line to stderr:

[trutisui] #15 tid=4892 FAIL malloc(1024) @ 0x55d8f61c205e
[trutisui] summary: 16 calls, 1 faults injected
  • #15: The global sequence number across all threads (this was the 15th allocation requested by the app).
  • tid=4892: The OS-level thread ID that requested the failing memory.
  • FAIL malloc(1024): The type of allocation and requested params.
  • @ 0x55d8f61c205e: The exact memory address of the caller in your binary.
    • Tip: Use addr2line -e ./my_app 0x55d8f61c205e to find the exact file and line of source code that crashed.

Example

dummy.c

#define _GNU_SOURCE 
#include <stdlib.h>

int main(void) {
  char *a = (char *)malloc(10);
  char *b = (char *)calloc(1, 10);
  char *c = (char *)realloc(a, 20);

  void *d;
  posix_memalign(&d, 16, 32);

  void *e = aligned_alloc(16, 32);
  
  return 0;
}

Execution & Output

We run the dummy app (compiled with O0 else the calls will be optimised away) with TRUTISUI_FAIL_AFTER=2. This means the first 2 allocations (malloc and calloc) will succeed normally, but the 3rd (realloc), 4th (posix_memalign), and 5th (aligned_alloc) will be intercepted and forcibly failed.

$ TRUTISUI_FAIL_AFTER=2 LD_PRELOAD=/path/to/trutisui/build/libtrutisui.so ./dummy

[trutisui] #2 tid=776978 FAIL realloc(0x561fe66e805e, 20) @ 0x561fe66e806b
[trutisui] #3 tid=776978 FAIL posix_memalign(16, 32) @ 0x561fe66e807a
[trutisui] #4 tid=776978 FAIL aligned_alloc(16, 32) @ 0x561fe66e8089
[trutisui] summary: 5 calls, 3 faults injected
truti (त्रुटि) is fault and sui (सुई) is injection in Hindi. i know very creative...

About

A small Dynamic Memory Fault Injector

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages