* You can enter the debugger with Dbg() or <CTRL-ALT-d>. You might enter the debugger through a fault. Enter G() or G2() to continue execution. Place a call to Dbg() in your code at fatal error points to enter the debugger. If you see a stk dump, record the label+offset and unassemble, U(). U(_RIP); * U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a function. U(_RIP-16); * While debugging, you specify addresses of assembly routines with just the label, as in _MALLOC+0x20. You specify HolyC function names with & before functions as in &Print+0x10. * I use progress1-progress4 for debugging because they show on the wallpaper. They're just global int vars. * You can use AdamLog() to send text to the Adam Task window. It works like Print(). I never use that. Instead, I use RawPrint(). * D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero. With DocD the values are updated continually and you can alter mem by editing. * Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing. * Da() to do one column address dump (for stk, etc.) with symbolic addresses. * Dr() dumps regs. You can display and modify regs in the debugger with var-like labels, _RAX, _RBX, etc. * ClassRep() and the dynamic version ClassRepD() can be used to dump structures. * Prof() and ProfRep() provide code profiling. See ::/Demo/InFile/InProfile.IN (This is an InFile.) * Use RawPrint() to print debug info bypassing the window framework. You pass these routines a count in milliseconds for how long it should be displayed. You can use Raw(TRUE) to make all output bypass the window framework. The WinMgr runs on Core0 and will overwrite raw text from other cores when it updates the scrn. * Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to trigger some debug activity. It's just a handy simple flag, nothing fancy. * There are flags for various trace options that can help debugging when there are compiler bugs. Often, you place them in #exe{} blocks. Echo() turns on or off raw data going into the lexical analyzer. Trace() unassembles code generated from the HolyC compiler. PassTrace() shows intermediate code coming-out after optimization. The bits ctrl which passes are displayed. * There is a heap check utility which can find leaks. Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep(). It's a really simple program which intercepts MAlloc() and Free(). You can customize the code to find other heap issues. * You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). They operate either in a interrupt environment or in the window mgr when it queues kbd msgs. You can do Raw() output. <CTRL-ALT-letter> hndlrs take a scan_code as an arg. * If you recompile Kernel with BootHDIns(), you can set the MemInit, option to initialize memory to a value at boot, the HeapInit option to cause mem alloced off the heap to be initialized or VarInit option so both global and local vars will be initialized to a value, but global AOT variables are always zero if not initialized. Pick a non-zero value to discover uninitialized var bugs. You can set sys_var_init_flag, and sys_heap_init_flag directly after booting.
Debugging Overview