xiaohongshu
xiaohongshu
fix-ocaml-gc
Guide for debugging and fixing bugs in the OCaml garbage collector runtime, particularly issues in memory management code like sweeping, pool management, and run-length compression. This skill should be used when encountering segfaults during OCaml bootstrap, debugging crashes in runtime/shared_h...
Full skill instructions
This skill provides systematic approaches for debugging and fixing bugs in the OCaml garbage collector, with particular focus on the multicore runtime's shared heap implementation. GC bugs are notoriously difficult because they often manifest as intermittent crashes, may only appear during bootstrap builds, and involve complex pointer arithmetic in low-level C code.
Apply this skill when encountering:
runtime/shared_heap.c or related GC filesBefore debugging, understand the OCaml build process:
Locate build documentation: Check for HACKING.adoc, INSTALL, or CONTRIBUTING.md files that explain the build process and testing infrastructure.
Understand bootstrap stages: OCaml bootstraps itself in stages:
Identify the failure point: Determine which stage crashes and what operation triggers it (compilation, linking, running tests).
Build with debug symbols: Ensure debug symbols are available for meaningful stack traces:
./configure --enable-debug-runtime
make clean && make world.opt
Obtain stack trace: Use GDB to get a stack trace at the crash point:
gdb --args ./ocamlopt.opt <crashing_args>
(gdb) run
(gdb) bt
Identify the crashing function: Note which function crashed and the memory address involved. For GC bugs, common crash locations include:
pool_sweep / caml_sweep_poolpool_allocateExamine memory state: Check pointer values and header contents:
(gdb) p/x pointer_var
(gdb) x/4gx block_address
Search for relevant code: Use grep to find sweep-related or allocator-related files:
grep -r "pool_sweep\|sweep" runtime/
grep -r "Wosize_hd\|Whsize_hd" runtime/
Understand data structures: Before modifying code, understand:
Read surrounding comments: GC code often has detailed comments explaining invariants and design decisions. Pay special attention to comments about:
Trace the algorithm manually: Work through the code by hand with concrete values to understand what should happen vs what is happening.
Identify pointer arithmetic patterns: Look for code that advances pointers through memory:
p += Whsize_hd(hd); // Advance by header-indicated size
p += wh; // Advance by fixed block size
p += wh * count; // Advance by multiple blocks
Check for inconsistent size usage: A common bug pattern in run-length encoded data:
wosize field may store a COUNT, not a SIZEWosize_hd(hd) where it should use fixed block sizewh) instead of computed sizeConsider multiple failure modes: A crash may have multiple root causes:
Make minimal changes: Fix only the identified bug without refactoring surrounding code.
Add clarifying comments: Document the fix and why the original code was wrong:
/* Advance by fixed block size wh, not Whsize_hd(hd).
* In run-length encoding, wosize stores the count of consecutive
* free blocks, not the actual block size. */
p += wh;
Check for similar patterns: Search the codebase for similar bug patterns:
grep -n "Whsize_hd\|Wosize_hd" runtime/shared_heap.c
Basic build test: Verify the project builds successfully:
make world.opt
Bootstrap test: Complete a full bootstrap to verify GC stability under heavy use:
make bootstrap
Run test suites: Execute ALL relevant test suites, not just basic tests:
make tests # Full test suite
cd testsuite && make # Alternative test runner
Run GC-specific tests: Look for and run GC-focused tests:
make -C testsuite/tests/gc-roots
make -C testsuite/tests/weakref
make -C testsuite/tests/ephemerons
Run parallel/multicore tests: For multicore GC bugs, test concurrent behavior:
make -C testsuite/tests/parallel
make -C testsuite/tests/domain
Memory sanitizers: If available, run with AddressSanitizer:
./configure CC="gcc -fsanitize=address"
make clean && make world.opt
Valgrind testing: Run test programs under Valgrind:
valgrind --leak-check=full ./program
Stress testing: Create or run memory-intensive test programs that exercise the specific code path.
Wrong: Find a plausible bug, fix it, and declare success after basic tests pass.
Right: Verify the hypothesis with debugging output or assertions before committing to the fix. Consider whether multiple bugs may exist.
Wrong: Only run tests/basic and assume the fix is complete.
Right: Run the full test suite including GC-specific tests, parallel tests, and stress tests. A GC bug can manifest in many scenarios.
Wrong: Fix pointer arithmetic based on pattern matching without understanding what header fields mean.
Right: Fully understand the data structure layout:
wosize mean for free blocks vs allocated blocks?wh) vs variable size?Wrong: Fix one occurrence of a bug pattern without checking for similar issues elsewhere.
Right: Search for all occurrences of the same pattern and verify each is correct:
grep -n "pattern" runtime/*.c
Wrong: Ignore errors like make: *** [check-failstamp] Error 1 as "infrastructure issues."
Right: Investigate all test failures. Infrastructure errors may indicate real problems or may mask actual test failures.
Wrong: Assume build succeeded because no immediate errors were displayed.
Right: Verify build completed fully:
ls -la ocamlopt.opt ocamlc.opt # Check binaries exist
make world.opt 2>&1 | tail -20 # Check for trailing errors
When fixing GC bugs, verify behavior in these scenarios:
Add printf debugging to verify hypotheses:
fprintf(stderr, "sweep: p=%p hd=%lx wosize=%lu wh=%lu\n",
(void*)p, hd, Wosize_hd(hd), wh);
# Break at specific function
(gdb) break pool_sweep
# Conditional breakpoint
(gdb) break shared_heap.c:644 if wosize > 1000
# Watch memory location
(gdb) watch *0x7ffff7000000
# Print header interpretation
(gdb) p/x Hd_val(block)
(gdb) p Wosize_hd(Hd_val(block))
If possible, compare against a working version:
git diff <known-good-commit> -- runtime/shared_heap.c
git log --oneline runtime/shared_heap.c # Find relevant commits
Before declaring a GC bug fixed, verify:
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience