infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
811_fault_injection.c File Reference

Unit test to verify resource cleanup under memory allocation failures. More...

#include "common/double_tap.h"
#include <infix/infix.h>
#include <stddef.h>
#include <pthread.h>
Include dependency graph for 811_fault_injection.c:

Macros

#define infix_malloc   test_malloc
 
#define infix_calloc   test_calloc
 
#define infix_free   test_free
 
#define infix_realloc   test_realloc
 
#define DBLTAP_IMPLEMENTATION
 
#define ALLOCATOR_LOCK()   pthread_mutex_lock(&allocator_mutex)
 
#define ALLOCATOR_UNLOCK()   pthread_mutex_unlock(&allocator_mutex)
 
#define ALLOCATOR_INIT()   ((void)0)
 

Functions

void setup_fault_injector (int fail_after_n_allocs)
 
void reset_fault_injector ()
 
void * test_malloc (size_t size)
 
void * test_calloc (size_t num, size_t size)
 
void test_free (void *ptr)
 
void * test_realloc (void *ptr, size_t new_size)
 
void fault_injection_handler (void)
 
 subtest ("Leak test for infix_forward_create failures")
 
 subtest ("Leak test for infix_reverse_create_callback failures")
 
 subtest ("Leak test for infix_type_from_signature failures")
 

Variables

static int allocation_countdown = -1
 
static int allocation_counter = 0
 
static bool fault_triggered = false
 
static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER
 
 TEST
 

Detailed Description

Unit test to verify resource cleanup under memory allocation failures.

This test uses a fault injection technique to test the library's resilience to memory allocation failures. It overrides the standard malloc and calloc functions with custom versions (test_malloc, test_calloc) that can be configured to fail after a specific number of successful allocations.

The test strategy is as follows:

  1. It iterates from N = 0 to a maximum limit.
  2. In each iteration N, it configures the custom allocator to fail on the N-th allocation.
  3. It then calls a complex infix API function (e.g., infix_forward_create).
  4. If the allocation failure was triggered, it asserts that the API function correctly returned an INFIX_ERROR_ALLOCATION_FAILED status.

The most important part of this test is not the assertion itself, but running it under a memory analysis tool like Valgrind or AddressSanitizer (ASan). A "pass" for this test is a clean report from the memory tool, which proves that even when an allocation fails midway through an operation, the infix library correctly cleans up all memory it had allocated up to that point, preventing memory leaks in error paths.

Macro Definition Documentation

◆ ALLOCATOR_INIT

ALLOCATOR_INIT ( )    ((void)0)

◆ ALLOCATOR_LOCK

#define ALLOCATOR_LOCK ( )    pthread_mutex_lock(&allocator_mutex)

◆ ALLOCATOR_UNLOCK

#define ALLOCATOR_UNLOCK ( )    pthread_mutex_unlock(&allocator_mutex)

◆ DBLTAP_IMPLEMENTATION

#define DBLTAP_IMPLEMENTATION

◆ infix_calloc

#define infix_calloc   test_calloc

◆ infix_free

#define infix_free   test_free

◆ infix_malloc

#define infix_malloc   test_malloc

◆ infix_realloc

#define infix_realloc   test_realloc

Function Documentation

◆ fault_injection_handler()

void fault_injection_handler ( void  )

◆ reset_fault_injector()

void reset_fault_injector ( )

◆ setup_fault_injector()

void setup_fault_injector ( int  fail_after_n_allocs)

◆ subtest() [1/3]

subtest ( "Leak test for infix_forward_create failures"  )

◆ subtest() [2/3]

subtest ( "Leak test for infix_reverse_create_callback failures"  )

◆ subtest() [3/3]

subtest ( "Leak test for infix_type_from_signature failures"  )

◆ test_calloc()

void * test_calloc ( size_t  num,
size_t  size 
)

◆ test_free()

void test_free ( void *  ptr)

◆ test_malloc()

void * test_malloc ( size_t  size)

◆ test_realloc()

void * test_realloc ( void *  ptr,
size_t  new_size 
)

Variable Documentation

◆ allocation_countdown

int allocation_countdown = -1
static

◆ allocation_counter

int allocation_counter = 0
static

◆ allocator_mutex

pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER
static

◆ fault_triggered

bool fault_triggered = false
static

◆ TEST

TEST
Initial value:
{
plan(3)
#define plan(count)
Definition double_tap.h:163