(system-include "carp_debug.h") (defmodule Debug (doc sanitize-addresses "Instruct the compiler to sanitize addresses.") (defdynamic sanitize-addresses [] (add-cflag "-fsanitize=address")) (register memory-balance (Fn [] Long)) (register reset-memory-balance! (Fn [] ())) (register log-memory-balance! (Fn [Bool] ())) (doc memory-logged "Log all calls to memory allocation within te form. Requires compiling with --log-memory.") (defmacro memory-logged [form] (list 'do '(Debug.log-memory-balance! true) form '(Debug.log-memory-balance! false))) (doc assert-balanced "Raises an error if the memory balance (numberr of alloc:s - number of free:s) isn't 0. Requires compiling with --log-memory.") (defmacro assert-balanced [form] (list 'let '[balance (Debug.memory-balance)] (list 'do (list 'let [] form) '(if (= balance (Debug.memory-balance)) () (do (IO.println &(fmt "Invalid memory balance: %d" (Debug.memory-balance))) (System.exit 1))) ()))) (doc trace "Print the value of an expression to stdout, then return its value.") (defmacro trace [x] (list 'let-do (array 'tmp x) (list 'IO.println (list 'ref (list 'fmt "%s:%d:%d: %s" (file x) (line x) (column x) '&(str tmp)))) 'tmp) ) (doc leak-array "Leak some memory. Useful for testing tools that detect leaks.") (register leak-array (Fn [a] ()) "Debug_leak_MINUS_array") ) ;; Crash the program with an error message unless the expression evaluates to 'true'. (defmacro assert [expr] (list 'if (list '= true expr) () (list 'do (list 'println* (list 'fmt "Assertion '%s' failed at line %d, column %d in file %s" (str expr) (line) (column) (file))) '(System.exit 1))))