Turning Sporadic iOS Wild‑Pointer Crashes into Deterministic Failures

This article explains how to convert rare, non‑reproducible Obj‑C wild‑pointer crashes into consistently repeatable crashes by delaying memory release, retaining freed memory in a custom queue, and safely managing it under memory‑pressure conditions.

Tencent TDS Service
Tencent TDS Service
Tencent TDS Service
Turning Sporadic iOS Wild‑Pointer Crashes into Deterministic Failures

Continuing from the previous discussion on locating Obj‑C wild‑pointer random crashes, this article shows how to make a non‑deterministic crash become deterministic.

Previously we filled the memory about to be freed with 0x55 so that accessing a wild pointer would more likely crash, but the filled memory can be overwritten by other allocations, keeping the crash probability low.

To increase the crash rate we avoid actually freeing the memory. Instead of calling free, we keep the memory in a custom queue and only release parts of it when the retained size exceeds a threshold or when the system issues a memory‑warning.

UIView* testObj=[[UIView alloc] init];
[testObj release];

for (int i=0; i<10; i++) {
    UIView* testView=[[[UIView alloc initWithFrame:CGRectMake(0,200,CGRectGetWidth(self.view.bounds), 60)] autorelease];
    [self.view addSubview:testView];
    [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:nil];
}

[testObj setNeedsLayout];

The core implementation uses a thread‑safe queue ( DSQueue) to store pointers to the retained memory. When the queue length or total retained size exceeds predefined limits, a batch of memory is released. The safe_free function either queues the memory after filling it with 0x55 or releases a batch if limits are reached.

DSQueue* _unfreeQueue=NULL; // queue for retained memory
int unfreeSize=0; // total retained size
#define MAX_STEAL_MEM_SIZE (1024*1024*100)
#define MAX_STEAL_MEM_NUM  (1024*1024*10)
#define BATCH_FREE_NUM    100

void free_some_mem(size_t freeNum){
    size_t count=ds_queue_length(_unfreeQueue);
    freeNum = freeNum>count ? count : freeNum;
    for (int i=0; i<freeNum; i++) {
        void* p = ds_queue_get(_unfreeQueue);
        size_t sz = malloc_size(p);
        __sync_fetch_and_sub(&unfreeSize, sz);
        orig_free(p);
    }
}

void safe_free(void* p){
    int cnt = ds_queue_length(_unfreeQueue);
    if (cnt>MAX_STEAL_MEM_NUM*0.9 || unfreeSize>MAX_STEAL_MEM_SIZE) {
        free_some_mem(BATCH_FREE_NUM);
    } else {
        size_t sz = malloc_size(p);
        memset(p, 0x55, sz);
        __sync_fetch_and_add(&unfreeSize, sz);
        ds_queue_put(_unfreeQueue, p);
    }
}

bool init_safe_free(){
    _unfreeQueue = ds_queue_create(MAX_STEAL_MEM_NUM);
    orig_free = (void(*)(void*))dlsym(RTLD_DEFAULT, "free");
    rebind_symbols1((struct rebinding[]){{"free", (void*)safe_free}}, 1);
    return true;
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    free_some_mem(1024*1024);
}

Key points to remember:

Avoid using locked functions inside safe_free to prevent deadlocks.

The approach increases the app’s memory footprint; it must never be shipped in production.

On devices like iPhone 5 the performance impact is acceptable, but multithreaded scenarios may increase crash rates.

By retaining more memory, the probability that a wild pointer accesses overwritten data rises, making crashes easier to reproduce and debug.

In theory, the larger the retained memory, the higher the crash probability.

Finally, the article encourages developers to share their own crash‑reproduction tricks to improve overall development quality.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSMemory ManagementObjective‑CCrash ReproductionSafe Free
Tencent TDS Service
Written by

Tencent TDS Service

TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.