# How to Handle the Fragile Base Class Problem in the Mulle-ObjC Runtime

> Learn how the mulle-objc runtime prevents fragile base class crashes by computing and comparing ivar layout hashes at load time. Ensure runtime stability and understand mismatch handling.

- Repository: [mulle-objc/mulle-objc-runtime](https://github.com/mulle-objc/mulle-objc-runtime)
- Tags: how-to-guide
- Published: 2026-03-07

---

**TLDR:** The mulle-objc runtime prevents fragile base class crashes by computing and comparing ivar layout hashes at load time, aborting execution on mismatches unless you explicitly set `ignore_ivarhash_mismatch` in the universe configuration.

The fragile base class problem has plagued Objective-C developers for decades, causing subtle memory corruption when superclass layouts change after subclass compilation. The **mulle-objc** runtime eliminates this risk through runtime ivar hash verification that detects binary incompatibilities before they trigger crashes. This guide explains how to handle the fragile base class problem using the runtime's built-in safety mechanisms and configuration options.

## What Is the Fragile Base Class Problem?

In Objective-C, a subclass inherits the instance-variable layout of its superclass. If the superclass adds, removes, or reorders ivars after the subclass was compiled, the subclass may read from or write to incorrect memory locations—a classic **fragile base class** bug that leads to data corruption or crashes.

The mulle-objc runtime protects against this at **load time** by comparing a hash of the ivar layout stored in the binary (`ivarhash`) with the hash computed from the currently loaded superclass. When a mismatch is detected in [`src/mulle-objc-load.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-load.c) (lines 374–376), the runtime aborts the load and prints a diagnostic message.

## Runtime Protection Mechanisms

### Ivar-Hash Verification During Loading

The primary defense resides in [`src/mulle-objc-load.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-load.c) at lines 374–376. During class loading, the runtime reads the ivar layout hash from the class's loadinfo (`classivarhash` and `superclassivarhash`) and compares it against the already-loaded superclass's computed hash (`superclass->ivarhash`).

If the hashes differ, the runtime raises a fatal error via `mulle_objc_load_error`, preventing the program from continuing with an inconsistent object layout. The default behavior demonstrates this protection:

```c
// No special configuration – the runtime will abort on mismatched ivar layouts
struct _mulle_objc_universe *universe = mulle_objc_universe_create(NULL, NULL);

/* Loading a class that has a different ivar layout than its superclass produces:
 *
 *   $ ./myprogram
 *   *** Fatal error: class 'SubClass' ivar hash 0x12345678 does not match
 *   *** superclass 'SuperClass' ivar hash 0x9abcdef0
 */

```

### Universe Configuration Flag

For advanced scenarios where you control all binaries and know the layout change is safe, the runtime provides an escape hatch. In [`src/mulle-objc-universe-struct.h`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-universe-struct.h) (line 69), the `struct _mulle_objc_universeconfig` contains the `ignore_ivarhash_mismatch` field.

When this flag is set to `1`, the runtime logs a warning in [`src/mulle-objc-universe.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-universe.c) (lines 103–104) and continues loading despite the mismatch:

```c
#include "mulle-objc-universe.h"

int main(void)
{
    struct _mulle_objc_universeconfig config = { 0 };
    config.ignore_ivarhash_mismatch = 1;   // Disable fragile-base protection

    struct _mulle_objc_universe *universe = mulle_objc_universe_create(&config, NULL);
    // Loading continues even if ivar hashes disagree
}

```

### Separate Inheritance Metadata

While unrelated to the fragile base class protection itself, the runtime stores per-class inheritance schemes separately to maintain clean metadata boundaries. The `inheritance` field defined in [`src/mulle-objc-class-struct.h`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-class-struct.h) (lines 58–60) and accessed via functions in [`src/mulle-objc-class.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-class.c) illustrates how the runtime keeps method lookup metadata distinct from ivar layout concerns.

You can inspect this field using the accessor functions defined in [`src/mulle-objc-class.h`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-class.h):

```c
#include "mulle-objc-class.h"

void show_inheritance(struct _mulle_objc_class *cls)
{
    unsigned int inh = _mulle_objc_class_get_inheritance(cls);
    printf("Inheritance scheme for %s: %u\n", _mulle_objc_class_get_name(cls), inh);
}

```

## When to Keep Protection Enabled

You should retain the default strict checking in the following scenarios:

- **Library code** used by third-party clients—prevents binary incompatibilities that would crash client applications
- **Development builds**—catches layout changes early before they cause subtle memory corruption  
- **Multiple runtime universes**—each universe performs independent checks, preventing cross-universe contamination

## Internal Implementation Walkthrough

The verification process follows these steps:

1. During class loading, the runtime extracts the ivar layout hash from the class's loadinfo structure (`classivarhash` and `superclassivarhash`) as implemented in [`src/mulle-objc-load.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-load.c) (lines 374–381)
2. It compares this against the loaded superclass's computed `ivarhash` 
3. If hashes differ and `ignore_ivarhash_mismatch` is **false**, the runtime aborts with `mulle_objc_load_error`
4. If the flag is **true**, execution continues after emitting a warning via the universe logging mechanism in [`src/mulle-objc-universe.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-universe.c)

Thus, the runtime provides a hard safety net by default while allowing expert users to bypass verification when they have complete control over all involved binaries.

## Summary

- The fragile base class problem occurs when superclass ivar layout changes break subclass memory addressing
- **mulle-objc** prevents this via `ivarhash` comparison in [`src/mulle-objc-load.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-load.c) (lines 374–376)
- Mismatches cause fatal errors by default, protecting against data corruption
- Set `ignore_ivarhash_mismatch` in `struct _mulle_objc_universeconfig` to bypass the check for controlled deployments
- Keep protection enabled when shipping libraries or running multiple universes

## Frequently Asked Questions

### What causes the fragile base class problem in Objective-C?

The fragile base class problem stems from Objective-C's inheritance model where subclasses hardcode offsets into their superclass's instance variable layout. When the superclass adds, removes, or reorders ivars after the subclass was compiled, the subclass accesses wrong memory locations, causing corruption or crashes.

### How does mulle-objc detect ivar layout mismatches?

The runtime computes a hash of each class's ivar layout (`ivarhash`) and stores it in the binary's loadinfo. At load time, in [`src/mulle-objc-load.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-load.c), it compares the subclass's expected superclass hash against the actual loaded superclass's hash. Divergence indicates an incompatible layout change.

### Can I disable the fragile base class protection?

Yes. Set the `ignore_ivarhash_mismatch` field to `1` in your `struct _mulle_objc_universeconfig` before calling `mulle_objc_universe_create()`. The runtime will log a warning via [`src/mulle-objc-universe.c`](https://github.com/mulle-objc/mulle-objc-runtime/blob/main/src/mulle-objc-universe.c) (lines 103–104) and continue loading. Only use this when you fully control and trust all binaries in your deployment.

### What happens if I ignore an ivar hash mismatch?

If you disable the check, the runtime permits loading to continue despite layout discrepancies. This risks memory corruption if the subclass accesses what it believes are inherited ivars at incorrect offsets. Only disable this protection when you have verified that the layout change does not affect the subclass's correctness or when performing emergency debugging.