naksheap: reconstruct heap object graphs from core dumps

Rust workspace that turns a core dump of a stripped, optimized C/C++
binary into a typed heap object graph: objects, sizes, allocator state,
references, and probable struct layouts, all without debug info.

- glibc ptmalloc carving (main + thread arenas, tcache/fastbin freed
  state, mmap allocations), ELF core + memory-list minidump parsing
- pointer scan, layout clustering, vtable/string/vector detection,
  confidence + evidence on every node
- ASCII/JSON/Graphviz/HTML output, synthetic fixtures with ground truth,
  and real-dump validation harness (aarch64 glibc 2.39) in scripts/
- web deployment reference stack in deploy/

MIT OR Apache-2.0
This commit is contained in:
lakshit verma 2026-08-15 04:21:59 +05:30
commit a48b163683
No known key found for this signature in database
59 changed files with 10518 additions and 0 deletions

16
fixtures/README.md Normal file
View file

@ -0,0 +1,16 @@
# fixtures
Generated artifacts, not hand-edited sources.
| File | Contents |
|---|---|
| toy-server.core | A deterministic synthetic ELF64 core dump |
| toy-server.core.manifest.json | The ground-truth manifest for that core: arenas, objects, roots, edges |
Regenerate from the repo root:
```sh
cargo run -p naksheap-testkit --example gen_fixture -- fixtures
```
The build is byte-for-byte deterministic. This golden core guards against regressions in the parser, carver, and scanner.

BIN
fixtures/toy-server.core Normal file

Binary file not shown.

View file

@ -0,0 +1,115 @@
{
"pointer_width": 8,
"pid": 4242,
"process_name": "toy-server",
"command_line": "./toy-server --listen :8080 --workers 4",
"exec_path": "/opt/app/toy-server",
"heap_base": 139637976727552,
"heap_end": 139637976743936,
"arenas": [
{
"addr": 140368121171968,
"size": 16384,
"top": 139637976727824,
"is_main": true
}
],
"objects": [
{
"addr": 139637976727568,
"size": 32,
"state": "allocated",
"arena": 140368121171968,
"chunk_header": 139637976727552,
"label": "head"
},
{
"addr": 139637976727616,
"size": 32,
"state": "allocated",
"arena": 140368121171968,
"chunk_header": 139637976727600,
"label": "second"
},
{
"addr": 139637976727664,
"size": 32,
"state": "allocated",
"arena": 140368121171968,
"chunk_header": 139637976727648,
"label": "tail"
},
{
"addr": 139637976727712,
"size": 64,
"state": "allocated",
"arena": 140368121171968,
"chunk_header": 139637976727696,
"label": "payload"
},
{
"addr": 139637976727792,
"size": 32,
"state": "freed",
"arena": 140368121171968,
"chunk_header": 139637976727776,
"label": "freed_slot"
}
],
"roots": [
{
"addr": 140733193404368,
"value": 139637976727568,
"kind": "stack",
"target_label": "head"
},
{
"addr": 14,
"value": 139637976727568,
"kind": "register",
"target_label": "head"
}
],
"edges": [
{
"from_addr": 139637976727568,
"from_label": "head",
"offset": 0,
"to_addr": 139637976727616,
"to_label": "second",
"kind": "heap"
},
{
"from_addr": 139637976727616,
"from_label": "second",
"offset": 0,
"to_addr": 139637976727664,
"to_label": "tail",
"kind": "heap"
},
{
"from_addr": 139637976727664,
"from_label": "tail",
"offset": 0,
"to_addr": 139637976727568,
"to_label": "head",
"kind": "heap"
},
{
"from_addr": 139637976727712,
"from_label": "payload",
"offset": 0,
"to_addr": 139637976727568,
"to_label": "head",
"kind": "heap"
},
{
"from_addr": 139637976727712,
"from_label": "payload",
"offset": 8,
"to_addr": 140368121184384,
"to_label": null,
"kind": "rodata"
}
]
}