Debugging Overview

* 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.