Embedding › 06 Operations

Operations

Build with sanitizers, diagnose the usual failures, and know the current limits.

1. Building and testing hosts

make                       # VM objects + CLI
make libs                  # standard library plugins
make clean                 # after switching sanitizer modes

# AddressSanitizer / UndefinedBehaviorSanitizer
make clean && make CFLAGS="-O0 -std=gnu11 -g -fsanitize=address,undefined"

# ThreadSanitizer (concurrency bugs)
make tsan

Hosts link whatever objects are present, so a sanitizer build of the host must match a sanitizer build of the VM. Always make clean between modes. When linking a host, exclude the CLI entry point:

cc -O2 -std=gnu11 -I src host.c $(ls src/*.o | grep -v '/main.o$') \
   -rdynamic -lm -ldl -lpthread -o host

2. Troubleshooting

SymptomCause and fix
module load failedA dependency was loaded after its user. Load the closure in order (chapter 3).
[native] no implementation found for X (.so missing)The native library was not found. Check native_set_lib_dir, and run make libs.
undefined symbol: vm_... at load timeThe host was linked without -rdynamic.
Crash inside vm_destroyA worker thread is still running. Join every thread first; check vm_live_threads.
Values turn into garbage after a whileAn unrooted Value was kept across allocations. Root it.
A run never endsNo step budget. Set vm_set_max_steps or the LOTH_MAX_STEPS environment variable for CLI runs.
Two VMs see different singletonsExpected: singletons are per VM. Use one shared VM if components must share state.

3. Limits worth knowing