Basics
Tracing is an important way to debug when coding in CM programming language. Useful tracing functions can be seen below:
/** * pln and ptrace. */ pln("Hello World!"); ptrace(); // displays trace location. /** * Short stack dump. */ ssd(); // shows full runtime stack from main. ssd(4); // shows x number of stack from the current runtime. /** * Print time. */ pln(#microTime); /** * Measure time taken for code execution. */ double t1 = microTime(); // some code here... pln(us(microTime - t1));
ptime
A syntax, ptime
, that measures time is available so you can quickly identify performance problems.
/** * ptime prints the time it takes to execute the code inside {} in developMode. * The code-'block' is treated as a series of statements so any * local variable inside will be visible outside ptime. */ { int i; ptime(spnn("Timing test ", i, " takes")) { sleep(50); int a = 3; } pln(#a); i++; ptime(spnn("Timing test ", i, " takes")) { sleep(100); int b = 4; } pln(#a; #b); }
Output:
Timing test 0 takes 50 ms 141 us a=3 Timing test 1 takes 100 ms 764 us a=3, b=4
Keywords of ptime
:
warning
= timespan time threshold - print only if the threshold is exceededrelease
= enable time measurement for releasevisible
= print ifvisible
is true (and warning threshold is exceeded)safe
= put statements inside try block
ptime("Warning - this takes too long:", warning=10ms, visible=true) { sleep(20); }
Profiler
If, for example, you need more information than ptime
can supply, the profiler is great to use when debugging a performance issue.
use cm.runtime.debug; { profiler.reset(); profiler.all(); profiler.start(); // some code here ... profiler.stop(); pln(profiler.report(20)); }
A syntax pprof
(experimental) exists, for convenient use of the profiler:
use cm.runtime.debug; pprof { for (snapper in mainSpace.snappers) { snapper.invalidate(); } }
Flags
There are few important debug flags that are available in code that can be used.
- Load drawing flags
In cm/core/stream/loadDrawingTimer.cm, there is a loadDrawingTimerEnabled flag which can be used when you want to debug a load drawing issue.
public bool loadDrawingTimerEnabled = true;
By setting this field to true, you can see all your hooks, loaded0, and loaded1 in your buffer in Emacs when loading your drawing.
2. Flush space
In cm/core/world.cm, there is a dbg_traceWorldFlushTime flag which tells the time of how long each flush took.
public bool dbg_traceWorldFlushTime = true;
3. Undo redo
When you need to see the time it took for the undo and redo time, you can use the dbg_traceUndoRedoTime field located in cm/core/undo/undoChain.cm.
public bool dbg_traceUndoRedoTime = true;
When you need to debug an undo crash, the undoChain.cm file is also the place to check. You can run that file or use the debug() function to dump all undo stack of each operation in your buffer in Emacs.
Comments
0 comments
Please sign in to leave a comment.