build: add --enable-asan with builtin leakcheck
authorKarl Skomski <karl@skomski.com>
Fri, 14 Aug 2015 08:07:18 +0000 (10:07 +0200)
committerRod Vagg <rod@vagg.org>
Sun, 6 Sep 2015 11:39:00 +0000 (21:39 +1000)
PR-URL: https://github.com/nodejs/node/pull/2376
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
common.gypi
configure
src/node.cc
test/sequential/test-child-process-emfile.js
tools/lsan_suppressions.txt [new file with mode: 0644]

index 7972c2d..7819816 100644 (file)
     },
     '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': [
index 42817c2..6c8dfde 100755 (executable)
--- 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
index 57fb6df..d62ed28 100644 (file)
 #include <string.h>
 #include <sys/types.h>
 
+#if defined(LEAK_SANITIZER)
+#include <sanitizer/lsan_interface.h>
+#endif
+
 #if defined(_MSC_VER)
 #include <direct.h>
 #include <io.h>
@@ -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;
   }
index 08a34a0..c4c467c 100644 (file)
@@ -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 (file)
index 0000000..46887b6
--- /dev/null
@@ -0,0 +1,4 @@
+# Usage: LSAN_OPTIONS=suppressions=`pwd`/tools/lsan_suppressions.txt make check
+
+# Suppress small (intentional) leaks in glibc
+leak:libc.so