Address Sanitizer¶
GCC and Clang support address sanitizer, which will use of uninitialized memory, accessing freed memory, accessing outside memory bounds, and so on. It also supports leak checking when Blender exits.
Enable with the WITH_COMPILER_ASAN
option in the CMake configuration.
It is also enabled when using make developer
to enable development
options.
Debugging¶
When the output is not enough to go by, run inside a debugger and break on the error reporting function
Example stack trace:
#0 0x00007ffff4e63e40 in __asan_report_error () from /usr/lib/libasan.so.0
#1 0x00007ffff4e5e804 in __asan_report_load1 () from /usr/lib/libasan.so.0
#2 0x0000000002450a77 in mywrite (wd=0x600c0028cd60, adr=0x602c00048340, len=376) at ./source/blender/blenloader/intern/writefile.c:297
#3 0x0000000002451413 in writedata (wd=0x600c0028cd60, filecode=1096040772, len=376, adr=0x602c00048340) at ./source/blender/blenloader/intern/writefile.c:395
#4 0x0000000002462edc in write_texts (wd=0x600c0028cd60, idbase=0x60500000f5c8) at ./source/blender/blenloader/intern/writefile.c:2679
#5 0x0000000002466826 in write_file_handle (mainvar=0x60500000f080, handle=0, compare=0x6044000158d0, current=0x60440004a5d0, write_user_block=0, write_flags=4608, thumb=0x0) at ./source/blender/blenloader/intern/writefile.c:3284
#6 0x0000000002467631 in BLO_write_file_mem (mainvar=0x60500000f080, compare=0x6044000158d0, current=0x60440004a5d0, write_flags=4608) at ./source/blender/blenloader/intern/writefile.c:3485
#7 0x0000000001e0105b in BKE_write_undo (C=0x60160000af90, name=0x3007820 "Open Text Block") at ./source/blender/blenkernel/intern/blender.c:676
#8 0x0000000000d34ee6 in ED_undo_push (C=0x60160000af90, str=0x3007820 "Open Text Block") at ./source/blender/editors/util/undo.c:110
#9 0x0000000000d356ba in ED_undo_push_op (C=0x60160000af90, op=0x601e00005b30) at ./source/blender/editors/util/undo.c:220
#10 0x000000000088ec97 in wm_handler_fileselect_call (C=0x60160000af90, handlers=0x60240007cd50, handler=0x601a0004b390, event=0x6018001cf180) at ./source/blender/windowmanager/intern/wm_event_system.c:1622
#11 0x000000000088fc90 in wm_handlers_do_intern (C=0x60160000af90, event=0x6018001cf180, handlers=0x60240007cd50) at ./source/blender/windowmanager/intern/wm_event_system.c:1816
#12 0x0000000000890237 in wm_handlers_do (C=0x60160000af90, event=0x6018001cf180, handlers=0x60240007cd50) at ./source/blender/windowmanager/intern/wm_event_system.c:1891
#13 0x00000000008919bc in wm_event_do_handlers (C=0x60160000af90) at ./source/blender/windowmanager/intern/wm_event_system.c:2138
#14 0x00000000008781dd in WM_main (C=0x60160000af90) at ./source/blender/windowmanager/intern/wm.c:447
#15 0x000000000087648a in main (argc=1, argv=0x7fffffffe058) at ./source/creator/creator.c:16
Quiet LeakSanitizer¶
While this tool is really useful to detect memory leaks, it has some annoying drawback in Blender currently - usage of Python leads to a fair amount of (valid!) leak reports, about which we cannot do much currently (see also Python documentation).
To silence those warnings (which can “hide” a real new one in the flow), you can use a suppression file. Such a file, tested on current linux platforms, is provided in Blender source tools.
It can be used by setting an environment variable like this, possibly in
.bashrc
or similar to make it permanent.
export LSAN_OPTIONS="print_suppressions=false:suppressions=/path/to/blender/source/tools/config/analysis/lsan.supp"
Most warnings will come from Python and graphics drivers, the common ones are included in the aforementioned file. More can be added as needed, using library and function names, including wildcards.
Note that it will remove any leak reports from code which backtrace contains a reference to libpython - this may be too generic, in which case just filtering out leaks coming from our bpy init code can be an option:
Running Blender with ASAN in GDB¶
Using Blender with ASAN in GDB can be more involved as you may need to
set environment variables for Blender to start (at time of writing
initialization-order-fiasco
causes startup to fail).
You may use this to run tests too. For tests you may wish to disable
ASAN's leak_check_at_exit
option as it causes any leaks (even those
generated by 3rd party libraries) to have a non-zero exit-code, causing
the test to fail.
gdb --ex=r --args env ASAN_OPTIONS=check_initialization_order=0:leak_check_at_exit=0 /path/to/blender --factory-startup --python ./tests/python/bl_pyapi_idprop.py
Running Blender Tests with ASAN¶
When running CTests, it's only necessary to ensure Blender starts and leak's don't change Blender's exit-code,
Comparison with Valgrind¶
Address sanitizer can help find bugs that Valgrind would, but there are some important differences.
Pros
- Fast enough for general use.
- Easy to use a breakpoint to investigate the point when and error
happens.
(Valgrind can use GDB too but its a bit more involved).
Cons
- Only deals with heap memory (not stack like valgrind).
- Can't be used with valgrind
(to use valgrind you'll have to remove the compiler flags and rebuild).
Further Reading¶
This feature is quite in-depth and this doc only explains basic usage, for further reading: