the ROSETTA STONE for one crash. ------------------------------------------------------------ One faulting operation, written once in C, exists at EVERY level: SOURCE : *p = 0xABCD; (the C statement) LLVM IR : store i32 43981, ptr %3 (43981 == 0xABCD) ASM : movl $0xabcd, (%rax) (rax holds the bad pointer) The same write shows up three times. Debugging is learning to recognize it at each level, and being able to START at the bottom (the register that holds the bad address, where the CPU actually trapped) and walk UP to the IR instruction and then the source line. We use the distinctive constant 0xABCD (= 43981) on purpose: you can grep for "43981" in the .ll and for "0xabcd" in the .s and find the SAME store. Build & trace (run from cross_level/, local LLVM on PATH): clang -g -O0 rosetta.c -o rosetta gdb -q -batch -ex run -ex bt -ex 'x/i $pc' -ex 'info registers rax rip' ./rosetta clang -g -O0 -S -emit-llvm rosetta.c -o rosetta.ll # the IR store clang -g -O0 -S rosetta.c -o rosetta.s # the asm store (See cross_level/README.md for the REAL captured output and the 3-row table.) ============================================================
int store_through(int *p) {
*p = 0xABCD; /* THE faulting operation: store 0xABCD through p (p==NULL) */
return *p;
}
int main(void) {
int *p = 0; /* null pointer */
return store_through(p);
}A lab is done when you can say what it showed on your machine — not when you have read it.
It decides which problems come first, which drills open, which labs you see and how the Learn surface is organised. Change it any time from the switch in the top bar, or press Escape to look around first.