subdir('meson/systemd') # Systemd and unit file handling
subdir('meson/code-coverage') # Code coverage
subdir('meson/auto-var-init') # Automatic Variable Initialization
+subdir('meson/sanitizers') # Sanitizers
# Find or generate pdns/dnslabeltext.cc
if not ragel.found() and not fs.exists('pdns/dnslabeltext.cc')
--- /dev/null
+# Address Sanitizer
+# Inputs: conf
+
+opt_address_sanitizer = get_option('sanitizer-address')
+
+if not opt_address_sanitizer
+ subdir_done()
+endif
+
+if not cxx.has_argument('-fsanitize=address')
+ error('Address Sanitizer requested but compiler does not support `-fsanitize=address`')
+endif
+
+if not cxx.check_header('sanitizer/common_interface_defs.h')
+ error('Address Sanitizer requested but `sanitizer/common_interface_defs.h` is invalid or cannot be found')
+endif
+
+if not cxx.has_header_symbol('sanitizer/common_interface_defs.h', '__sanitizer_start_switch_fiber', required: false)
+ warning('Address Sanitizer fiber switching is not available')
+endif
+
+single_pointer = false
+prog_single_pointer = '''
+#include <sanitizer/common_interface_defs.h>
+
+int main() {
+ __sanitizer_finish_switch_fiber(nullptr);
+ return 0;
+}
+'''
+
+three_pointers = false
+prog_three_pointers = '''
+#include <sanitizer/common_interface_defs.h>
+
+int main() {
+ __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr);
+ return 0;
+}
+'''
+
+if cxx.compiles(prog_single_pointer, name: '__sanitizer_finish_switch_fiber with a single pointer')
+ single_pointer = true
+endif
+
+if cxx.compiles(prog_three_pointers, name: '__sanitizer_finish_switch_fiber with three pointers')
+ three_pointers = true
+endif
+
+if not single_pointer and not three_pointers
+ warning('Address Sanitizer fiber switching is not available due to an unknown API version')
+endif
+
+conf.set10('HAVE_FIBER_SANITIZER', single_pointer or three_pointers, description: 'Address Sanitizer fiber annotation interface is available')
+conf.set10('HAVE_SANITIZER_FINISH_SWITCH_FIBER_SINGLE_PTR', single_pointer, description: 'Address Sanitizer: __sanitizer_finish_switch_fiber takes only a pointer')
+conf.set10('HAVE_SANITIZER_FINISH_SWITCH_FIBER_THREE_PTRS', three_pointers, description: 'Address Sanitizer: __sanitizer_finish_switch_fiber takes three pointers')
+
+add_global_arguments('-fsanitize=address')
+
+summary('address', opt_address_sanitizer, bool_yn: true, section: 'Sanitizers')
--- /dev/null
+# Sanitizers
+
+subdir('address-sanitizer')
+
+sanitizers = {
+ 'memory': 'Memory',
+ 'thread': 'Thread',
+ 'leak': 'Leak',
+ 'undefined': 'Undefined Behavior',
+}
+
+foreach sanitizer, name: sanitizers
+ opt_name = 'opt_' + sanitizer + '_sanitizer'
+ set_variable(opt_name, get_option('sanitizer-' + sanitizer))
+
+ if not get_variable(opt_name)
+ continue
+ endif
+
+ compiler_opt = '-fsanitize=' + sanitizer
+ if not cxx.has_argument(compiler_opt)
+ error(name + ' Sanitizer requested but compiler does not support `' + compiler_opt + '`')
+ endif
+ add_global_arguments(compiler_opt)
+ summary(name, get_variable(opt_name), bool_yn: true, section: 'Sanitizers')
+endforeach
+
+if opt_address_sanitizer and opt_thread_sanitizer
+ error('Address Sanitizer is not compatible with Thread Sanitizer')
+endif
+
+if opt_memory_sanitizer and opt_address_sanitizer
+ error('Memory Sanitizer is not compatible with Address Sanitizer')
+endif
+
+if opt_memory_sanitizer and opt_leak_sanitizer
+ error('Memory Sanitizer is not compatible with Leak Sanitizer')
+endif
+
+if opt_memory_sanitizer and opt_thread_sanitizer
+ error('Memory Sanitizer is not compatible with Thread Sanitizer')
+endif
+
+if opt_address_sanitizer or opt_thread_sanitizer or opt_leak_sanitizer or opt_undefined_behavior_sanitizer or opt_memory_sanitizer
+ add_global_arguments('-fno-omit-frame-pointer')
+endif
option('systemd-service-group', type: 'string', value: 'pdns', description: 'Systemd service group (setgid and unit file; group is not created)')
option('code-coverage', type: 'boolean', value: false, description: 'Enable code coverage')
option('auto-var-init', type: 'combo', value: 'disabled', choices: ['zero', 'pattern', 'disabled'], description: 'Enable initialization of automatic variables')
+option('sanitizer-address', type: 'boolean', value: false, description: 'Enable the Address Sanitizer')
+option('sanitizer-memory', type: 'boolean', value: false, description: 'Enable the Memory Sanitizer')
+option('sanitizer-thread', type: 'boolean', value: false, description: 'Enable the Thread Sanitizer')
+option('sanitizer-leak', type: 'boolean', value: false, description: 'Enable the Leak Sanitizer')
+option('sanitizer-undefined', type: 'boolean', value: false, description: 'Enable the Undefined Behavior Sanitizer')