diff --git a/common.gypi b/common.gypi index 7972c2d60a..7819816bbb 100644 --- a/common.gypi +++ b/common.gypi @@ -173,16 +173,34 @@ }, 'msvs_disabled_warnings': [4351, 4355, 4800], 'conditions': [ - ['asan != 0', { + ['asan == 1 and OS != "mac"', { 'cflags+': [ '-fno-omit-frame-pointer', '-fsanitize=address', - '-w', # http://crbug.com/162783 + '-DLEAK_SANITIZER' ], 'cflags_cc+': [ '-gline-tables-only' ], 'cflags!': [ '-fomit-frame-pointer' ], 'ldflags': [ '-fsanitize=address' ], }], + ['asan == 1 and OS == "mac"', { + 'xcode_settings': { + 'OTHER_CFLAGS+': [ + '-fno-omit-frame-pointer', + '-gline-tables-only', + '-fsanitize=address', + '-DLEAK_SANITIZER' + ], + 'OTHER_CFLAGS!': [ + '-fomit-frame-pointer', + ], + }, + 'target_conditions': [ + ['_type!="static_library"', { + 'xcode_settings': {'OTHER_LDFLAGS': ['-fsanitize=address']}, + }], + ], + }], ['OS == "win"', { 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin 'defines': [ diff --git a/configure b/configure index 42817c21eb..6c8dfde432 100755 --- a/configure +++ b/configure @@ -335,6 +335,11 @@ parser.add_option('--xcode', dest='use_xcode', help='generate build files for use with xcode') +parser.add_option('--enable-asan', + action='store_true', + dest='enable_asan', + help='build with asan') + parser.add_option('--enable-static', action='store_true', dest='enable_static', @@ -707,6 +712,7 @@ def configure_node(o): if options.linked_module: o['variables']['library_files'] = options.linked_module + o['variables']['asan'] = int(options.enable_asan or 0) def configure_library(lib, output): shared_lib = 'shared_' + lib diff --git a/src/node.cc b/src/node.cc index 57fb6df24e..d62ed28355 100644 --- a/src/node.cc +++ b/src/node.cc @@ -52,6 +52,10 @@ #include #include +#if defined(LEAK_SANITIZER) +#include +#endif + #if defined(_MSC_VER) #include #include @@ -3967,6 +3971,10 @@ static void StartNodeInstance(void* arg) { instance_data->set_exit_code(exit_code); RunAtExit(env); +#if defined(LEAK_SANITIZER) + __lsan_do_leak_check(); +#endif + env->Dispose(); env = nullptr; } diff --git a/test/sequential/test-child-process-emfile.js b/test/sequential/test-child-process-emfile.js index 08a34a05f2..c4c467c339 100644 --- a/test/sequential/test-child-process-emfile.js +++ b/test/sequential/test-child-process-emfile.js @@ -9,9 +9,11 @@ if (common.isWindows) { return; } +var openFds = []; + for (;;) { try { - fs.openSync(__filename, 'r'); + openFds.push(fs.openSync(__filename, 'r')); } catch (err) { assert(err.code === 'EMFILE' || err.code === 'ENFILE'); break; @@ -27,3 +29,8 @@ proc.on('error', common.mustCall(function(err) { // 'exit' should not be emitted, the process was never spawned. proc.on('exit', assert.fail); + +// close one fd for LSan +if (openFds.length >= 1) { + fs.closeSync(openFds.pop()); +} diff --git a/tools/lsan_suppressions.txt b/tools/lsan_suppressions.txt new file mode 100644 index 0000000000..46887b62ae --- /dev/null +++ b/tools/lsan_suppressions.txt @@ -0,0 +1,4 @@ +# Usage: LSAN_OPTIONS=suppressions=`pwd`/tools/lsan_suppressions.txt make check + +# Suppress small (intentional) leaks in glibc +leak:libc.so