merging in the most recent version of everything else
diff --git a/.gitignore b/.gitignore
index 5bfc69f..0d20b64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
 *.pyc
-output/
diff --git a/aos/atom_code/ipc_lib/aos_sync.h b/aos/atom_code/ipc_lib/aos_sync.h
index 6d4bf55..ddbe3d0 100644
--- a/aos/atom_code/ipc_lib/aos_sync.h
+++ b/aos/atom_code/ipc_lib/aos_sync.h
@@ -48,6 +48,8 @@
 // They are designed for signalling when something happens (possibly to
 // multiple listeners). A mutex manipulated with them can only be set or unset.
 //
+// Another name for this kind of synchronization mechanism is a "notification".
+//
 // They are different from the condition_ functions in that they do NOT work
 // correctly as standard condition variables. While it is possible to keep
 // track of the "condition" using the value part of the futex_* functions, the
diff --git a/aos/atom_code/ipc_lib/ipc_lib.gyp b/aos/atom_code/ipc_lib/ipc_lib.gyp
index f947d5e..af9d779 100644
--- a/aos/atom_code/ipc_lib/ipc_lib.gyp
+++ b/aos/atom_code/ipc_lib/ipc_lib.gyp
@@ -61,6 +61,7 @@
         'core_lib',
         '<(AOS)/common/common.gyp:queue_testutils',
         '<(AOS)/common/common.gyp:time',
+        '<(AOS)/common/common.gyp:die',
       ],
     },
     {
@@ -77,6 +78,9 @@
         'core_lib',
         '<(AOS)/common/common.gyp:die',
       ],
+      'variables': {
+        'is_special_test': 1,
+      },
     },
   ],
 }
diff --git a/aos/atom_code/ipc_lib/ipc_stress_test.cc b/aos/atom_code/ipc_lib/ipc_stress_test.cc
index 38c425f..6c40926 100644
--- a/aos/atom_code/ipc_lib/ipc_stress_test.cc
+++ b/aos/atom_code/ipc_lib/ipc_stress_test.cc
@@ -212,7 +212,10 @@
   new (shared) Shared(time::Time::Now() + kTestTime);
 
   char *temp = strdup(argv[0]);
-  shared->path = strdup(dirname(temp));
+  if (asprintf(const_cast<char **>(&shared->path),
+               "%s/../tests", dirname(temp)) == -1) {
+    Die("asprintf failed with %d: %s\n", errno, strerror(errno));
+  }
   free(temp);
 
   for (int i = 0; i < kTesters; ++i) {
diff --git a/aos/atom_code/ipc_lib/queue_test.cc b/aos/atom_code/ipc_lib/queue_test.cc
index 9e5f3ae..dda40af 100644
--- a/aos/atom_code/ipc_lib/queue_test.cc
+++ b/aos/atom_code/ipc_lib/queue_test.cc
@@ -15,6 +15,7 @@
 #include "aos/common/queue_testutils.h"
 #include "aos/common/time.h"
 #include "aos/common/logging/logging.h"
+#include "aos/common/die.h"
 
 using ::testing::AssertionResult;
 using ::testing::AssertionSuccess;
@@ -136,6 +137,9 @@
 
   void SetUp() override {
     ::testing::Test::SetUp();
+
+    SetDieTestMode(true);
+
     fatal_failure = static_cast<char *>(shm_malloc(sizeof(fatal_failure)));
     static bool registered = false;
     if (!registered) {
diff --git a/aos/build/aos.gypi b/aos/build/aos.gypi
index 0f7d4b6..f27361b 100644
--- a/aos/build/aos.gypi
+++ b/aos/build/aos.gypi
@@ -74,6 +74,15 @@
     'include_dirs': [
       '<(DEPTH)',
     ],
+    # These have to be here because apparently gyp evaluates target_conditions
+    # even if the target is never used.
+    'variables': {
+      # Set this to 1 to disable rsyncing the file to the target.
+      'no_rsync%': 0,
+      # Set this to 1 if this file isn't a test that should get run by
+      # `build.sh tests`.
+      'is_special_test%': 0,
+    },
     'conditions': [
       ['DEBUG=="yes"', {
           'cflags': [
@@ -149,9 +158,6 @@
             'NOMINMAX',
           ],
         }, {
-          'variables': {
-            'no_rsync%': 0,
-          },
           'target_conditions': [
 # default to putting outputs into rsync_dir
             ['no_rsync==0 and _type!="static_library"', {
diff --git a/aos/build/build.sh b/aos/build/build.sh
index 4b36e7e..09fe83c 100755
--- a/aos/build/build.sh
+++ b/aos/build/build.sh
@@ -91,6 +91,6 @@
 END
   fi
   if [[ ${ACTION} == tests ]]; then
-    find ${OUTDIR}/tests -executable -exec {} \;
+    find ${OUTDIR}/tests -executable -exec ${AOS}/build/run_test.sh {} \;
   fi
 fi
diff --git a/aos/build/download_externals.sh b/aos/build/download_externals.sh
index 5b759a8..5868637 100755
--- a/aos/build/download_externals.sh
+++ b/aos/build/download_externals.sh
@@ -68,7 +68,7 @@
 
 # get gtest
 GTEST_VERSION=1.6.0
-GTEST_DIR=${EXTERNALS}/gtest-${GTEST_VERSION}
+GTEST_DIR=${EXTERNALS}/gtest-${GTEST_VERSION}-p1
 GTEST_ZIP=${EXTERNALS}/gtest-${GTEST_VERSION}.zip
 [ -f ${GTEST_ZIP} ] || wget http://googletest.googlecode.com/files/gtest-${GTEST_VERSION}.zip -O ${GTEST_ZIP}
 [ -d ${GTEST_DIR} ] || ( unzip ${GTEST_ZIP} -d ${TMPDIR} && mv ${TMPDIR}/gtest-${GTEST_VERSION} ${GTEST_DIR} && cd ${GTEST_DIR} && patch -p1 < ${AOS}/externals/gtest.patch )
diff --git a/aos/build/externals.gyp b/aos/build/externals.gyp
index 836ddde..34564e1 100644
--- a/aos/build/externals.gyp
+++ b/aos/build/externals.gyp
@@ -9,7 +9,7 @@
 
 # These versions have to be kept in sync with the ones in download_externals.sh.
     'eigen_version': '3.1.3',
-    'gtest_version': '1.6.0',
+    'gtest_version': '1.6.0-p1',
     'onejar_version': '0.97',
     'ctemplate_version': '129',
     'gflags_version': '2.0',
@@ -176,9 +176,12 @@
       'direct_dependent_settings': {
         'include_dirs': ['<(externals)/gtest-<(gtest_version)/include'],
         'target_conditions': [
-          ['_type=="executable"', {
+          ['_type=="executable" and is_special_test==0', {
               'product_dir': '<(test_dir)',
             },
+          ], ['_type=="executable" and is_special_test==1', {
+              'product_dir': '<(test_dir)-special',
+            },
           ],
         ],
       },
diff --git a/aos/build/run_test.sh b/aos/build/run_test.sh
new file mode 100755
index 0000000..9da830b
--- /dev/null
+++ b/aos/build/run_test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# This gets called by build.sh to run a test.
+
+EXECUTABLE=$1
+
+echo "Running $(basename ${EXECUTABLE})."
+${EXECUTABLE}
+exit $?
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index d8c10e0..5958b7e 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -158,6 +158,7 @@
         'queue_testutils',
         'queue_test_queue',
         '<(AOS)/common/util/util.gyp:thread',
+        'die',
       ],
     },
     {
@@ -274,6 +275,7 @@
         '<(EXTERNALS):gtest',
         'mutex',
         '<(AOS)/build/aos.gyp:logging',
+        'die',
       ],
     },
     {
@@ -291,6 +293,7 @@
         '<(AOS)/build/aos.gyp:logging',
         'queue_testutils',
         '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:core_lib',
+        'die',
        ],
     },
     {
diff --git a/aos/common/condition_test.cc b/aos/common/condition_test.cc
index fca2820..7e74918 100644
--- a/aos/common/condition_test.cc
+++ b/aos/common/condition_test.cc
@@ -13,6 +13,7 @@
 #include "aos/atom_code/ipc_lib/core_lib.h"
 #include "aos/common/logging/logging.h"
 #include "aos/common/macros.h"
+#include "aos/common/die.h"
 
 using ::aos::time::Time;
 using ::aos::common::testing::GlobalCoreInstance;
@@ -43,6 +44,11 @@
     time::SleepFor(::Time::InSeconds(0.008));
   }
 
+ protected:
+  void SetUp() override {
+    SetDieTestMode(true);
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(ConditionTest);
 };
diff --git a/aos/common/die.cc b/aos/common/die.cc
index 467b81d..0ea7007 100644
--- a/aos/common/die.cc
+++ b/aos/common/die.cc
@@ -6,13 +6,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <string.h>
-#ifdef __VXWORKS__
-#include <taskLib.h>
-// Have to re-declare it with __attribute__((noreturn)).
-extern "C" void abort() __attribute__((noreturn));
-#include <usrLib.h>
-#include <dbgLib.h>
-#endif
+#include <signal.h>
 
 #include <string>
 
@@ -28,6 +22,7 @@
 }
 
 namespace {
+
 // Calculates the filename to dump the message into.
 const std::string GetFilename() {
 #ifdef __VXWORKS__
@@ -50,6 +45,9 @@
   }
 #endif
 }
+
+bool test_mode = false;
+
 }  // namespace
 
 void VDie(const char *format, va_list args_in) {
@@ -60,31 +58,28 @@
   fputs("aos fatal: ERROR!! details following\n", stderr);
   va_copy(args1, args_in);
   vfprintf(stderr, format, args1);
-  fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
+  if (!test_mode) {
+    fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
 
-  const std::string filename = GetFilename();
-  if (!filename.empty()) {
-    FILE *error_file = fopen(filename.c_str(), "w");
-    if (error_file != NULL) {
-      va_copy(args2, args_in);
-      vfprintf(error_file, format, args2);
-      fclose(error_file);
-    } else {
-      fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d (%s)\n",
-              filename.c_str(), errno, strerror(errno));
+    const std::string filename = GetFilename();
+    if (!filename.empty()) {
+      FILE *error_file = fopen(filename.c_str(), "w");
+      if (error_file != NULL) {
+        va_copy(args2, args_in);
+        vfprintf(error_file, format, args2);
+        fclose(error_file);
+      } else {
+        fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d (%s)\n",
+                filename.c_str(), errno, strerror(errno));
+      }
     }
   }
 
-#ifdef __VXWORKS__
-  printf("I am 0x%x suspending for debugging purposes.\n", taskIdSelf());
-  printf("\t`tt 0x%x` will give you a stack trace.\n", taskIdSelf());
-  fputs("\t`lkAddr` will reverse lookup a symbol for you.\n", stdout);
-  fputs("\t`dbgHelp` and `help` have some useful commands in them.\n", stdout);
-  taskSuspend(0);
-  printf("You weren't supposed to resume 0x%x!!. Going to really die now.\n",
-         taskIdSelf());
-#endif
   abort();
 }
 
+void SetDieTestMode(bool new_test_mode) {
+  test_mode = new_test_mode;
+}
+
 }  // namespace aos
diff --git a/aos/common/die.h b/aos/common/die.h
index 28519a8..d973b42 100644
--- a/aos/common/die.h
+++ b/aos/common/die.h
@@ -15,6 +15,11 @@
     __attribute__((noreturn))
     __attribute__((format(gnu_printf, 1, 0)));
 
+// Turns on (or off) "test mode", where (V)Die doesn't write out files and
+// doesn't print to stdout.
+// Test mode defaults to false.
+void SetDieTestMode(bool test_mode);
+
 }  // namespace aos
 
 #endif  // AOS_COMMON_DIE_H_
diff --git a/aos/common/mutex_test.cpp b/aos/common/mutex_test.cpp
index 652cd9e..10f4e0b 100644
--- a/aos/common/mutex_test.cpp
+++ b/aos/common/mutex_test.cpp
@@ -10,6 +10,7 @@
 #include "gtest/gtest.h"
 
 #include "aos/atom_code/ipc_lib/aos_sync.h"
+#include "aos/common/die.h"
 
 namespace aos {
 namespace testing {
@@ -17,6 +18,11 @@
 class MutexTest : public ::testing::Test {
  public:
   Mutex test_mutex;
+
+ protected:
+  void SetUp() override {
+    SetDieTestMode(true);
+  }
 };
 
 typedef MutexTest MutexDeathTest;
diff --git a/aos/common/queue_test.cc b/aos/common/queue_test.cc
index 32d1d23..ebb0bba 100644
--- a/aos/common/queue_test.cc
+++ b/aos/common/queue_test.cc
@@ -6,6 +6,7 @@
 #include "aos/common/test_queue.q.h"
 #include "aos/common/queue_testutils.h"
 #include "aos/common/util/thread.h"
+#include "aos/common/die.h"
 
 using ::aos::time::Time;
 
@@ -15,6 +16,10 @@
 
 class QueueTest : public ::testing::Test {
  protected:
+  void SetUp() override {
+    SetDieTestMode(true);
+  }
+
   GlobalCoreInstance my_core;
   // Create a new instance of the test queue so that it invalidates the queue
   // that it points to.  Otherwise, we will have a pointer to shared memory that
diff --git a/aos/externals/gtest.patch b/aos/externals/gtest.patch
index 6caba01..cbf7294 100644
--- a/aos/externals/gtest.patch
+++ b/aos/externals/gtest.patch
@@ -1,63 +1,50 @@
-diff -rupN gtest-1.6.0-p1/fused-src/gtest/gtest-all.cc gtest-1.6.0/fused-src/gtest/gtest-all.cc
---- gtest-1.6.0-p1/fused-src/gtest/gtest-all.cc	2011-04-15 12:54:57.000000000 -0700
-+++ gtest-1.6.0/fused-src/gtest/gtest-all.cc	2012-11-12 17:42:37.881573135 -0800
-@@ -379,7 +379,25 @@ class GTEST_API_ SingleFailureChecker {
+diff --git src/gtest-port.cc b/src/gtest-port.cc
+index b860d48..acb459b 100644
+--- a/src/gtest-port.cc
++++ b/src/gtest-port.cc
+@@ -98,6 +98,21 @@ size_t GetThreadCount() {
+   }
+ }
  
- // cpplint thinks that the header is already included, so we want to
- // silence it.
-+#ifdef __VXWORKS__
-+# include <time.h>  // NOLINT
-+# include <sys/times.h>  // NOLINT
-+static inline int gettimeofday(struct timeval *tv, void *) {
-+  struct timespec ts;
++#elif GTEST_OS_LINUX
 +
-+  if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
-+    printf("Gettimeofday error\n");
-+    tv->tv_sec = 0;
-+    tv->tv_usec = 0;
-+    return -1;
++size_t GetThreadCount() {
++  size_t thread_count = 0;
++  if (DIR *dir = opendir("/proc/self/task")) {
++    while (dirent *entry = readdir(dir)) {
++      if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
++        ++thread_count;
++      }
++    }
++    closedir(dir);
 +  }
-+  tv->tv_sec  = ts.tv_sec;
-+  tv->tv_usec = ts.tv_nsec/1000;
-+  return 0;
++  return thread_count;
 +}
-+#else
- # include <sys/time.h>  // NOLINT
-+#endif
- # include <unistd.h>  // NOLINT
- 
- #endif  // GTEST_OS_LINUX
-@@ -7751,6 +7769,8 @@ bool FilePath::CreateFolder() const {
-   delete [] unicode;
- #elif GTEST_OS_WINDOWS
-   int result = _mkdir(pathname_.c_str());
-+#elif defined(__VXWORKS__)
-+  int result = mkdir(pathname_.c_str());
- #else
-   int result = mkdir(pathname_.c_str(), 0777);
- #endif  // GTEST_OS_WINDOWS_MOBILE
-@@ -7870,7 +7890,7 @@ void FilePath::Normalize() {
- namespace testing {
- namespace internal {
- 
--#if defined(_MSC_VER) || defined(__BORLANDC__)
-+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__VXWORKS__)
- // MSVC and C++Builder do not provide a definition of STDERR_FILENO.
- const int kStdOutFileno = 1;
- const int kStdErrFileno = 2;
-diff -rupN gtest-1.6.0-p1/include/gtest/internal/gtest-port.h gtest-1.6.0/include/gtest/internal/gtest-port.h
---- gtest-1.6.0-p1/include/gtest/internal/gtest-port.h	2011-04-15 12:49:10.000000000 -0700
-+++ gtest-1.6.0/include/gtest/internal/gtest-port.h	2012-11-12 17:27:33.536801263 -0800
-@@ -197,6 +197,12 @@
- #include <sstream>  // NOLINT
- #include <string>  // NOLINT
- 
-+#ifdef __VXWORKS__
-+int read(int fd, void *buf, size_t count);
-+int write(int fd, const void *buf, size_t count);
-+int close(int fd);
-+#endif
 +
- #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
- #define GTEST_FLAG_PREFIX_ "gtest_"
- #define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+ #else
+ 
+ size_t GetThreadCount() {
+diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc
+index 8b2e413..faad3a4 100644
+--- a/src/gtest-death-test.cc
++++ b/src/gtest-death-test.cc
+@@ -44,6 +44,8 @@
+ # include <fcntl.h>
+ # include <limits.h>
+ # include <stdarg.h>
++# include <sys/time.h>
++# include <sys/resource.h>
+ 
+ # if GTEST_OS_WINDOWS
+ #  include <windows.h>
+@@ -898,6 +900,11 @@ inline char** GetEnviron() { return environ; }
+ // This function is called in a clone()-ed process and thus must avoid
+ // any potentially unsafe operations like malloc or libc functions.
+ static int ExecDeathTestChildMain(void* child_arg) {
++  rlimit core_rlimit;
++  core_rlimit.rlim_cur = 0;
++  core_rlimit.rlim_max = 0;
++  GTEST_DEATH_TEST_CHECK_SYSCALL_(setrlimit(RLIMIT_CORE, &core_limit));
++
+   ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+   GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
diff --git a/output/downloaded/.gitignore b/output/downloaded/.gitignore
index 079a15e..ecab071 100644
--- a/output/downloaded/.gitignore
+++ b/output/downloaded/.gitignore
@@ -4,7 +4,7 @@
 /eigen-3.1.3/
 /gccdist.zip
 /gccdist/
-/gtest-1.6.0/
+/gtest-1.6.0-p1/
 /gtest-1.6.0.zip
 /gyp-1738/
 /javacv-0.2-bin.zip