Debugging Overview

* You can enter the debugger with Debug() or <CTRL-ALT-d>.  You might enter the debugger through a fault.  Enter G() or G2() 
to continue execution.  Place a call to Debug() in your code at fatal error points to enter the debugger.  If you see a stack 
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 ZealC 
function names with & before functions as in &Print+0x10.

* You can use progress1-progress4 for debugging because they show on the wallpaper.  They're just global int variables.

* You can use SysLog() to send text to the System Task window.  It works like Print().  You could also use RawPrint().

* Dump(), DocDump(), RawDump() to do 16 column hex dump mem with numbering from zero.   With DocDump the values are updated 
continually and you can alter mem by editing.

* DumpMem(), DocDumpMem(), RawDumpMem() to do 16 column hex dump mem with addresses showing.

* DumpAddress() to do one column address dump (for stack, etc.) with symbolic addresses.

* DumpRegs() dumps registers.  You can display and modify registers in the debugger with variable-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 screen.

* Use SysDebug() to set a flag which you can read with IsSysDebug() 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 #e
xe{} blocks.
  
  Echo() turns on or off raw data going into the lexical analyzer.
  
  Trace() unassembles code generated from the ZealC 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 handler functions for <CTRL-ALT-letter> keys with CtrlAltCBSet().  They operate either in a interrupt 
environment or in the window mgr when it queues kbd messages.  You can do Raw() output.  <CTRL-ALT-letter> handlers 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 HeapI
nit option to cause mem alloced off the heap to be initialized or VarInit option so both global and local variables will be 
initialized to a value, but global AOT variables are always zero if not initialized.  Pick a non-zero value to discover 
uninitialized variable bugs.    You can set sys_var_init_flag, and sys_heap_init_flag directly after booting.