Tools: Enabling AddressSanitizer (ASan) in Makefile.PL for Linux Environments (2026)

Tools: Enabling AddressSanitizer (ASan) in Makefile.PL for Linux Environments (2026)

Add the 'asan-on-linux' Option

Automate Library Preloading via Makefile Macros

How to Handle Memory Issues

Appendix: Platform Compatibility

macOS (Untested Hint)

Windows (Not Supported) Note: This method is designed for Linux systems where LD_PRELOAD is available. AddressSanitizer (ASan) is a powerful tool for detecting memory corruption in C/C++ code. When developing Perl XS modules, you can integrate ASan support directly into your Makefile.PL to make debugging seamless. First, use GetOptions to provide a dedicated flag for ASan. This allows users to enable memory sanitization explicitly. We also set up a temporary directory to store ASan's detailed log files. Since the standard perl binary isn't typically compiled with ASan, we must ensure libasan.so is correctly preloaded before the interpreter starts. By using the macro parameter in WriteMakefile, we can automate this process for make test. When ASan is enabled, the behavior depends on the type of memory issue: ASan generates a separate log file for each process. To efficiently find both corruption reports and leaks related to your specific module, use the following Perl one-liner (Replace My::Module with your module's name): This command uses Perl's "paragraph mode" (-00) to extract the entire stack trace, allowing you to see exactly where the issue (crash or leak) was triggered in your native code. On macOS, you might try DYLD_INSERT_LIBRARIES instead of LD_PRELOAD. However, System Integrity Protection (SIP) often prevents preloading into system binaries like /usr/bin/perl. You would likely need to use a perl installed via perlbrew or plenv. This mechanism is not applicable to Windows. Windows lacks LD_PRELOAD, and memory sanitization requires a fundamentally different configuration, typically involving a specially compiled perl interpreter. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

$ use Getopt::Long; use File::Path 'mkpath'; GetOptions('asan-on-linux' => \my $asan_on_linux); my @ccflags; my @ldflags; my $asan_logs_dir = ".tmp/asan_logs"; if ($asan_on_linux) { push @ccflags, "-fsanitize=address", "-fno-omit-frame-pointer"; push @ldflags, "-fsanitize=address"; mkpath $asan_logs_dir unless -d $asan_logs_dir; } use Getopt::Long; use File::Path 'mkpath'; GetOptions('asan-on-linux' => \my $asan_on_linux); my @ccflags; my @ldflags; my $asan_logs_dir = ".tmp/asan_logs"; if ($asan_on_linux) { push @ccflags, "-fsanitize=address", "-fno-omit-frame-pointer"; push @ldflags, "-fsanitize=address"; mkpath $asan_logs_dir unless -d $asan_logs_dir; } use Config; WriteMakefile( NAME => 'My::Module', CCFLAGS => "$Config{ccflags} " . join(' ', @ccflags), LDDLFLAGS => "$Config{lddlflags} " . join(' ', @ldflags), # ... macro => { $asan_on_linux ? ( 'override FULLPERL' => qq|LD_PRELOAD=\$\$($Config{cc} -print-file-name=libasan.so) ASAN_OPTIONS="log_path=$asan_logs_dir/asan.log:exitcode=0" $^X| ) : (), }, ); use Config; WriteMakefile( NAME => 'My::Module', CCFLAGS => "$Config{ccflags} " . join(' ', @ccflags), LDDLFLAGS => "$Config{lddlflags} " . join(' ', @ldflags), # ... macro => { $asan_on_linux ? ( 'override FULLPERL' => qq|LD_PRELOAD=\$\$($Config{cc} -print-file-name=libasan.so) ASAN_OPTIONS="log_path=$asan_logs_dir/asan.log:exitcode=0" $^X| ) : (), }, ); perl -00 -ne 'print "--- File: $ARGV ---\n$_\n" if /My::Module/' .tmp/asan_logs/* > .tmp/asan_summary.log perl -00 -ne 'print "--- File: $ARGV ---\n$_\n" if /My::Module/' .tmp/asan_logs/* > .tmp/asan_summary.log - Memory Corruption: Issues like buffer overflows or use-after-free will cause a Segmentation Fault (Segfault) immediately. When this happens, you must fix the code until all tests pass without crashing. - Memory Leaks: Unlike corruption, memory leaks do not cause a crash. To find them, you must check the logs after running your tests.