added actual support for running clang with sanitizers
diff --git a/aos/build/aos.gypi b/aos/build/aos.gypi
index 917a8ca..334a5e3 100644
--- a/aos/build/aos.gypi
+++ b/aos/build/aos.gypi
@@ -63,27 +63,41 @@
           ['CC', '/opt/clang-3.5/bin/clang'],
           ['CXX', '/opt/clang-3.5/bin/clang++'],
         ],
+      },
+    ], ['PLATFORM=="linux-amd64-gcc"', {
+      },
+    ], ['SANITIZER!="none"', {
         'target_defaults': {
           'cflags': [
-            # TODO(brians): Always build with this in debug mode?
-            #'-fsanitize=address',
-
+            '-fsanitize=<(SANITIZER)',
             # TODO(brians): Figure out how to blacklist some bits of other
             # people's code (ie stdlibc++...) and then have it abort on failure.
             #'-fsanitize=undefined,integer',
-
-            # TODO(brians): Try and figure out how to get these 2 to work (it
-            # looks like they force using shared libraries which means building
-            # everything with -fPIC).
-            #'-fsanitize=memory',
-            #'-fsanitize=thread',
           ],
           'ldflags': [
-            #'-fsanitize=thread',
+            '-fsanitize=<(SANITIZER)',
           ],
         },
       },
-    ], ['PLATFORM=="linux-amd64-gcc"', {
+    ], ['SANITIZER_FPIC!=""', {
+        'target_defaults': {
+          'cflags': [
+            '-fPIC',
+          ],
+          'ldflags': [
+            '-fPIC',
+          ],
+        },
+      },
+    ], ['SANITIZER=="memory"', {
+        'target_defaults': {
+          'cflags': [
+            '-fsanitize-memory-track-origins',
+          ],
+          'ldflags': [
+            '-fsanitize-memory-track-origins',
+          ],
+        },
       },
     ],
   ],
@@ -261,6 +275,9 @@
                 'cflags': [
                   '-Wunused-local-typedefs',
                 ],
+                'defines': [
+                  '__has_feature(n)=0'
+                ],
               },
             ], ['COMPILER=="clang"', {
                 'cflags': [
diff --git a/aos/build/build.py b/aos/build/build.py
index b954379..208b380 100755
--- a/aos/build/build.py
+++ b/aos/build/build.py
@@ -122,19 +122,21 @@
 
 class PrimeProcessor(Processor):
   class Platform(Processor.Platform):
-    def __init__(self, architecture, compiler, debug):
+    def __init__(self, architecture, compiler, debug, sanitizer):
       super(PrimeProcessor.Platform, self).__init__()
 
       self.architecture = architecture
       self.compiler = compiler
       self.debug = debug
+      self.sanitizer = sanitizer
 
     def __repr__(self):
-      return 'PrimeProcessor.Platform(architecture=%s, compiler=%s, debug=%s)' \
-          % (self.architecture, self.compiler, self.debug)
+      return 'PrimeProcessor.Platform(architecture=%s, compiler=%s, debug=%s' \
+          ', sanitizer=%s)' \
+          % (self.architecture, self.compiler, self.debug, self.sanitizer)
     def __str__(self):
-      return '%s-%s%s' % (self.architecture, self.compiler,
-                          '-debug' if self.debug else '')
+      return '%s-%s%s-%s' % (self.architecture, self.compiler,
+                          '-debug' if self.debug else '', self.sanitizer)
 
     def os(self):
       return 'linux'
@@ -182,12 +184,19 @@
       r = {}
       if self.compiler == 'clang':
         r['LD_LIBRARY_PATH'] = '/opt/clang-3.5/lib64'
+      if self.sanitizer == 'address':
         r['ASAN_SYMBOLIZER_PATH'] = '/opt/clang-3.5/bin/llvm-symbolizer'
         r['ASAN_OPTIONS'] = 'detect_leaks=1:check_initialization_order=1:strict_init_order=1'
+      elif self.sanitizer == 'memory':
+        r['MSAN_SYMBOLIZER_PATH'] = '/opt/clang-3.5/bin/llvm-symbolizer'
       return r
 
   ARCHITECTURES = ['arm', 'amd64']
   COMPILERS = ['clang', 'gcc']
+  # TODO(brians): memory doesn't really work because we don't have everything
+  # instrumented. Print out a warning or something.
+  SANITIZERS = ['address', 'undefined', 'integer', 'memory', 'thread', 'none']
+  PIC_SANITIZERS = ['memory', 'thread']
 
   def __init__(self, is_test, is_deploy):
     super(Processor, self).__init__()
@@ -197,7 +206,11 @@
       for compiler in PrimeProcessor.COMPILERS:
         for debug in [True, False]:
           platforms.append(
-              PrimeProcessor.Platform(architecture, compiler, debug))
+              PrimeProcessor.Platform(architecture, compiler, debug, 'none'))
+    for sanitizer in PrimeProcessor.SANITIZERS:
+      if sanitizer != 'none':
+        platforms.append(
+            PrimeProcessor.Platform('amd64', 'clang', True, sanitizer))
     self.platforms = frozenset(platforms)
     if is_test:
       self.default_platforms = self.select_platforms(architecture='amd64',
@@ -232,18 +245,19 @@
           r = selected
     return r
 
-  def select_platforms(self, architecture=None, compiler=None, debug=None):
+  def select_platforms(self, architecture=None, compiler=None, debug=None, sanitizer=None):
     r = []
     for platform in self.platforms:
       if architecture is None or platform.architecture == architecture:
         if compiler is None or platform.compiler == compiler:
           if debug is None or platform.debug == debug:
-            r.append(platform)
+            if sanitizer is None or platform.sanitizer == sanitizer:
+              r.append(platform)
     return set(r)
 
   def select_platforms_string(self, string):
     r = []
-    architecture, compiler, debug = None, None, None
+    architecture, compiler, debug, sanitizer = None, None, None, None
     for part in string.split('-'):
       if part in PrimeProcessor.ARCHITECTURES:
         architecture = part
@@ -253,12 +267,15 @@
         debug = True
       elif part in ['release', 'nodebug', 'ndb']:
         debug = False
+      elif part in PrimeProcessor.SANITIZERS:
+        sanitizer = part
       else:
         raise Processor.UnknownPlatform('Unknown platform string component "%s".' % part)
     return self.select_platforms(
         architecture=architecture,
         compiler=compiler,
-        debug=debug)
+        debug=debug,
+        sanitizer=sanitizer)
 
   def check_installed(self):
     self.do_check_installed(
@@ -363,9 +380,17 @@
   if processor.is_crio():
     download_externals('crio')
   else:
+    to_download = set()
     for architecture in PrimeProcessor.ARCHITECTURES:
-      if platforms & processor.select_platforms(architecture=architecture):
-        download_externals(architecture)
+      for sanitizer in PrimeProcessor.PIC_SANITIZERS:
+        if platforms & processor.select_platforms(architecture=architecture,
+                                                  sanitizer=sanitizer):
+          to_download.add(architecture + '-fPIC')
+        if platforms & processor.select_platforms(architecture=architecture,
+                                                  sanitizer='none'):
+          to_download.add(architecture)
+    for download_target in to_download:
+      download_externals(download_target)
 
   class ToolsConfig(object):
     def __init__(self):
@@ -394,6 +419,8 @@
     raise excinfo[1]
 
   def need_to_run_gyp(platform):
+    if not os.path.exists(platform.build_ninja()):
+      return True
     dirs = os.listdir(os.path.join(aos_path(), '..'))
     # Looking through these folders takes a long time and isn't useful.
     dirs.remove('output')
@@ -430,7 +457,11 @@
              '-DPLATFORM=%s' % platform.gyp_platform(),
              '-DARCHITECTURE=%s' % platform.architecture,
              '-DCOMPILER=%s' % platform.compiler,
-             '-DDEBUG=%s' % ('yes' if platform.debug else 'no')) +
+             '-DDEBUG=%s' % ('yes' if platform.debug else 'no'),
+             '-DSANITIZER=%s' % platform.sanitizer,
+             '-DSANITIZER_FPIC=%s' % ('-fPIC'
+                 if platform.sanitizer in PrimeProcessor.PIC_SANITIZERS
+                 else '')) +
             processor.extra_gyp_flags() + (args.main_gyp,),
             stdin=subprocess.PIPE)
         gyp.communicate(("""
diff --git a/aos/build/download_externals.sh b/aos/build/download_externals.sh
index e643107..61e7b7d 100755
--- a/aos/build/download_externals.sh
+++ b/aos/build/download_externals.sh
@@ -23,10 +23,14 @@
   IS_CRIO=0
 elif [ "$1" == "amd64" ]; then
   COMPILED=${EXTERNALS}/../compiled-amd64
+  IS_CRIO=0
+elif [ "$1" == "amd64-fPIC" ]; then
+  COMPILED=${EXTERNALS}/../compiled-amd64-fPIC
 
-  export CFLAGS="-march=atom -mfpmath=sse"
-  export CXXFLAGS="-march=atom -mfpmath=sse"
-  CONFIGURE_FLAGS="CFLAGS=\"${CFLAGS}\" CXXFLAGS=\"${CXXFLAGS}\""
+  export CFLAGS="-fPIC"
+  export CXXFLAGS="-fPIC"
+  export LDFLAGS="-fPIC"
+  CONFIGURE_FLAGS="CFLAGS=\"${CFLAGS}\" CXXFLAGS=\"${CXXFLAGS}\" LDFLAGS=\"${LDFLAGS}\""
   IS_CRIO=0
 elif [ "$1" == "crio" ]; then
   IS_CRIO=1
diff --git a/aos/build/externals.gyp b/aos/build/externals.gyp
index 27c2512..ec7a2a1 100644
--- a/aos/build/externals.gyp
+++ b/aos/build/externals.gyp
@@ -5,8 +5,8 @@
     # TODO(brians): Would we not have to do this hackery if we named it externals_path etc?
     'externals': '<(AOS)/../output/downloaded',
     'externals_abs': '<!(readlink -f ../../output/downloaded)',
-    'compiled': '<(externals)/../compiled-<(ARCHITECTURE)',
-    'compiled_abs': '<(externals_abs)/../compiled-<(ARCHITECTURE)',
+    'compiled': '<(externals)/../compiled-<(ARCHITECTURE)<(SANITIZER_FPIC)',
+    'compiled_abs': '<(externals_abs)/../compiled-<(ARCHITECTURE)<(SANITIZER_FPIC)',
 
 # These versions have to be kept in sync with the ones in download_externals.sh.
     'eigen_version': '3.2.1',