got rid of all uses of strerror

This required some minor refactoring of other things and there were some
other small cleanups I noticed along the way.
diff --git a/aos/build/aos.gyp b/aos/build/aos.gyp
index a0412c3..916db03 100644
--- a/aos/build/aos.gyp
+++ b/aos/build/aos.gyp
@@ -25,6 +25,10 @@
       ],
       'dependencies': [
         '<(AOS)/common/common.gyp:die',
+        '<(AOS)/common/util/util.gyp:aos_strerror',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/common/util/util.gyp:aos_strerror',
       ],
     },
     {
@@ -53,6 +57,9 @@
         'logging_interface',
         '<(AOS)/common/common.gyp:queue_types',
       ],
+      'export_dependent_settings': [
+        'logging_interface',
+      ],
     },
   ],
 }
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index c989bf2..2581eaa 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -225,6 +225,12 @@
       'sources': [
         'die.cc',
       ],
+      'dependencies': [
+        '<(AOS)/common/util/util.gyp:aos_strerror',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/common/util/util.gyp:aos_strerror',
+      ],
     },
     {
       'target_name': 'condition',
@@ -277,6 +283,7 @@
         'mutex',
         'die',
         '<(AOS)/build/aos.gyp:logging',
+        '<(AOS)/common/util/util.gyp:death_test_log_implementation',
       ],
     },
     {
diff --git a/aos/common/die.cc b/aos/common/die.cc
index 4c579cd..e1b3b07 100644
--- a/aos/common/die.cc
+++ b/aos/common/die.cc
@@ -38,8 +38,8 @@
     return r;
   } else {
     fprintf(stderr, "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
-            " failed with %d (%s)\n", &filename,
-            static_cast<intmax_t>(getpid()), errno, strerror(errno));
+            " failed with %d\n", &filename,
+            static_cast<intmax_t>(getpid()), errno);
     return std::string();
   }
 #endif
@@ -68,8 +68,8 @@
         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));
+        fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d\n",
+                filename.c_str(), errno);
       }
     }
   }
diff --git a/aos/common/die.h b/aos/common/die.h
index 3c5cca9..05500be 100644
--- a/aos/common/die.h
+++ b/aos/common/die.h
@@ -4,6 +4,7 @@
 #include <stdarg.h>
 
 #include "aos/common/macros.h"
+#include "aos/common/util/aos_strerror.h"
 
 namespace aos {
 
@@ -17,6 +18,16 @@
     __attribute__((noreturn))
     __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 1, 0)));
 
+
+// The same as Die except appends " because of %d (%s)" (formatted with errno
+// and aos_strerror(errno)) to the message.
+#define PDie(format, args...)                               \
+  do {                                                      \
+    const int error = errno;                                \
+    ::aos::Die(format " because of %d (%s)", ##args, error, \
+               aos_strerror(error));                        \
+  } while (false);
+
 // 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.
diff --git a/aos/common/logging/logging.h b/aos/common/logging/logging.h
index 03f3e31..49828bf 100644
--- a/aos/common/logging/logging.h
+++ b/aos/common/logging/logging.h
@@ -7,8 +7,11 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
+#include <errno.h>
 
 #include "aos/common/macros.h"
+#include "aos/common/util/aos_strerror.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -36,6 +39,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 // Actually implements the basic logging call.
 // Does not check that level is valid.
 void log_do(log_level level, const char *format, ...)
@@ -47,6 +51,7 @@
 void log_uncork(int line, const char *function, log_level level,
                 const char *file, const char *format, ...)
   __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 6)));
+
 #ifdef __cplusplus
 }
 #endif
@@ -74,6 +79,17 @@
     }                                                                      \
   } while (0)
 
+// Same as LOG except appends " due to %d(%s)\n" (formatted with errno and
+// aos_strerror(errno)) to the message.
+#define PLOG(level, format, args...) PELOG(level, errno, format, ##args)
+
+// Like PLOG except allows specifying an error other than errno.
+#define PELOG(level, error_in, format, args...)                                \
+  do {                                                                         \
+    const int error = error_in;                                                \
+    LOG(level, format " due to %d(%s)\n", ##args, error, aos_strerror(error)); \
+  } while (0);
+
 // Allows format to not be a string constant.
 #define LOG_DYNAMIC(level, format, args...)                             \
   do {                                                                  \
diff --git a/aos/common/logging/logging_interface.cc b/aos/common/logging/logging_interface.cc
index ae8cc01..8c45afd 100644
--- a/aos/common/logging/logging_interface.cc
+++ b/aos/common/logging/logging_interface.cc
@@ -30,8 +30,8 @@
   const int ret = vsnprintf(output, size, format, ap);
   typedef ::std::common_type<typeof(ret), typeof(size)>::type RetType;
   if (ret < 0) {
-    LOG(FATAL, "vsnprintf(%p, %zd, %s, args) failed with %d (%s)\n",
-        output, size, format, errno, strerror(errno));
+    PLOG(FATAL, "vsnprintf(%p, %zd, %s, args) failed",
+         output, size, format);
   } else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
     // Overwrite the '\0' at the end of the existing data and
     // copy in the one on the end of continued.
diff --git a/aos/common/mutex_test.cpp b/aos/common/mutex_test.cpp
index f946dfa..2ab3e5c 100644
--- a/aos/common/mutex_test.cpp
+++ b/aos/common/mutex_test.cpp
@@ -11,6 +11,7 @@
 
 #include "aos/linux_code/ipc_lib/aos_sync.h"
 #include "aos/common/die.h"
+#include "aos/common/util/death_test_log_implementation.h"
 
 namespace aos {
 namespace testing {
@@ -49,12 +50,22 @@
 TEST_F(MutexDeathTest, RepeatUnlock) {
   test_mutex.Lock();
   test_mutex.Unlock();
-  EXPECT_DEATH(test_mutex.Unlock(), ".*multiple unlock.*");
+  EXPECT_DEATH(
+      {
+        logging::AddImplementation(new util::DeathTestLogImplementation());
+        test_mutex.Unlock();
+      },
+      ".*multiple unlock.*");
 }
 
 // Sees what happens if you unlock without ever locking (or unlocking) it.
 TEST_F(MutexDeathTest, NeverLock) {
-  EXPECT_DEATH(test_mutex.Unlock(), ".*multiple unlock.*");
+  EXPECT_DEATH(
+      {
+        logging::AddImplementation(new util::DeathTestLogImplementation());
+        test_mutex.Unlock();
+      },
+      ".*multiple unlock.*");
 }
 #endif
 
diff --git a/aos/common/network/receive_socket.cc b/aos/common/network/receive_socket.cc
index 76a7a80..c3a7710 100644
--- a/aos/common/network/receive_socket.cc
+++ b/aos/common/network/receive_socket.cc
@@ -23,8 +23,7 @@
 
   if (bind(socket_, &addr_.addr,
            sizeof(addr_)) == -1) {
-    LOG(ERROR, "failed to bind to address '%s' because of %d: %s\n", localhost,
-        errno, strerror(errno));
+    PLOG(ERROR, "failed to bind to address '%s'", localhost);
     return last_ret_ = -1;
   }
   return last_ret_ = 0;
diff --git a/aos/common/network/send_socket.cc b/aos/common/network/send_socket.cc
index 03bc57c..9886893 100644
--- a/aos/common/network/send_socket.cc
+++ b/aos/common/network/send_socket.cc
@@ -20,8 +20,7 @@
   }
 
   if (connect(socket_, &addr_.addr, sizeof(addr_)) < 0) {
-    LOG(ERROR, "couldn't connect to ip '%s' because of %d: %s\n", robot_ip,
-        errno, strerror(errno));
+    PLOG(ERROR, "couldn't connect to ip '%s'", robot_ip);
     return last_ret_ = 1;
   }
 
diff --git a/aos/common/network/socket.cc b/aos/common/network/socket.cc
index 4f6687e..b674ff1 100644
--- a/aos/common/network/socket.cc
+++ b/aos/common/network/socket.cc
@@ -13,8 +13,7 @@
 int Socket::Connect(NetworkPort port, const char *address, int type) {
   last_ret_ = 0;
   if ((socket_ = socket(AF_INET, type, 0)) < 0) {
-    LOG(ERROR, "failed to create socket because of %d: %s\n",
-        errno, strerror(errno));
+    PLOG(ERROR, "failed to create socket");
     return last_ret_ = 1;
   }
 
@@ -27,8 +26,7 @@
   const int failure_return = -1;
 #endif
   if (inet_aton(address, &addr_.in.sin_addr) == failure_return) {
-    LOG(ERROR, "Invalid IP address '%s' because of %d: %s\n", address,
-        errno, strerror(errno));
+    PLOG(ERROR, "invalid IP address '%s'", address);
     return last_ret_ = -1;
   }
 
@@ -69,8 +67,8 @@
       if (errno == EINTR) {
         return last_ret_ = 0;
       }
-      LOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed with %d: %s\n",
-          &fds, &timeout_timeval, errno, strerror(errno));
+      PLOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed",
+          &fds, &timeout_timeval);
   }
 }
 
diff --git a/aos/common/queue_testutils.cc b/aos/common/queue_testutils.cc
index 1b9b731..ed89d4f 100644
--- a/aos/common/queue_testutils.cc
+++ b/aos/common/queue_testutils.cc
@@ -128,7 +128,7 @@
                       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
   assert(memory != MAP_FAILED);
 
-  assert(aos_core_use_address_as_shared_mem(memory, kCoreSize) == 0);
+  aos_core_use_address_as_shared_mem(memory, kCoreSize);
 
   EnableTestLogging();
 }
diff --git a/aos/common/scoped_fd.h b/aos/common/scoped_fd.h
index eb22f80..57ecdd8 100644
--- a/aos/common/scoped_fd.h
+++ b/aos/common/scoped_fd.h
@@ -30,8 +30,7 @@
   void Close() {
     if (fd_ != -1) {
       if (close(fd_) == -1) {
-        LOG(WARNING, "close(%d) failed with %d: %s\n", fd_,
-            errno, strerror(errno));
+        PLOG(WARNING, "close(%d) failed", fd_);
       }
     }
   }
diff --git a/aos/common/time.cc b/aos/common/time.cc
index 88802e3..aa75eae 100644
--- a/aos/common/time.cc
+++ b/aos/common/time.cc
@@ -1,9 +1,5 @@
 #include "aos/common/time.h"
 
-#ifdef __VXWORKS__
-#include <taskLib.h>
-#endif
-#include <errno.h>
 #include <string.h>
 
 #include "aos/common/logging/logging.h"
@@ -34,8 +30,8 @@
 Time NowImpl(clockid_t clock) {
   timespec temp;
   if (clock_gettime(clock, &temp) != 0) {
-    LOG(FATAL, "clock_gettime(%jd, %p) failed with %d: %s\n",
-        static_cast<uintmax_t>(clock), &temp, errno, strerror(errno));
+    PLOG(FATAL, "clock_gettime(%jd, %p) failed",
+         static_cast<uintmax_t>(clock), &temp);
   }
   return Time(temp);
 }
@@ -192,53 +188,30 @@
 }
 
 void SleepFor(const Time &time, clockid_t clock) {
-#ifdef __VXWORKS__
-  SleepUntil(Time::Now(clock) + time, clock);
-#else
   timespec converted(time.ToTimespec()), remaining;
   int failure = EINTR;
   do {
     // This checks whether the last time through the loop actually failed or got
     // interrupted.
     if (failure != EINTR) {
-      LOG(FATAL, "clock_nanosleep(%jd, 0, %p, %p) returned %d: %s\n",
-          static_cast<intmax_t>(clock), &converted, &remaining,
-          failure, strerror(failure));
+      PELOG(FATAL, failure, "clock_nanosleep(%jd, 0, %p, %p) failed",
+            static_cast<intmax_t>(clock), &converted, &remaining);
     }
     failure = clock_nanosleep(clock, 0, &converted, &remaining);
     memcpy(&converted, &remaining, sizeof(converted));
   } while (failure != 0);
-#endif
 }
 
 void SleepUntil(const Time &time, clockid_t clock) {
-#ifdef __VXWORKS__
-  if (clock != CLOCK_REALTIME) {
-    LOG(FATAL, "vxworks only supports CLOCK_REALTIME\n");
-  }
-  // Vxworks nanosleep is definitely broken (fails horribly at doing remaining
-  // right), and I don't really want to know how else it's broken, so I'm using
-  // taskDelay instead because that's simpler.
-  // The +1 is because sleep functions are supposed to sleep for at least the
-  // requested amount, so we have to round up to the next clock tick.
-  while (taskDelay((time - Time::Now(clock)).ToTicks() + 1) != 0) {
-    if (errno != EINTR) {
-      LOG(FATAL, "taskDelay(some ticks) failed with %d: %s\n",
-          errno, strerror(errno));
-    }
-  }
-#else
   timespec converted(time.ToTimespec());
   int failure;
   while ((failure = clock_nanosleep(clock, TIMER_ABSTIME,
                                     &converted, NULL)) != 0) {
     if (failure != EINTR) {
-      LOG(FATAL, "clock_nanosleep(%jd, TIMER_ABSTIME, %p, NULL)"
-          " returned %d: %s\n", static_cast<intmax_t>(clock), &converted,
-          failure, strerror(failure));
+      PELOG(FATAL, failure, "clock_nanosleep(%jd, TIMER_ABSTIME, %p, NULL)"
+            " failed", static_cast<intmax_t>(clock), &converted);
     }
   }
-#endif
 }
 
 }  // namespace time
diff --git a/aos/common/util/aos_strerror.cc b/aos/common/util/aos_strerror.cc
new file mode 100644
index 0000000..d2b2ca6
--- /dev/null
+++ b/aos/common/util/aos_strerror.cc
@@ -0,0 +1,42 @@
+#include "aos/common/util/aos_strerror.h"
+
+#include <assert.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "aos/linux_code/thread_local.h"
+
+// This code uses an overloaded function to handle the result from either
+// version of strerror_r correctly without needing a way to get the choice out
+// of the compiler/glibc/whatever explicitly.
+
+namespace {
+
+const size_t kBufferSize = 128;
+
+// Handle the result from the GNU version of strerror_r. It never fails, so
+// that's pretty easy...
+__attribute__((unused))
+char *aos_strerror_handle_result(int /*error*/, char *ret, char * /*buffer*/) {
+  return ret;
+}
+
+// Handle the result from the POSIX version of strerror_r.
+__attribute__((unused))
+char *aos_strerror_handle_result(int error, int ret, char *buffer) {
+  if (ret != 0) {
+    assert(snprintf(buffer, kBufferSize, "Unknown error %d", error) > 0);
+  }
+  return buffer;
+}
+
+}  // namespace
+
+char *aos_strerror(int error) {
+  static AOS_THREAD_LOCAL char buffer[kBufferSize];
+
+  // Call the overload for whichever version we're using.
+  return aos_strerror_handle_result(
+      error, strerror_r(error, buffer, sizeof(buffer)), buffer);
+}
diff --git a/aos/common/util/aos_strerror.h b/aos/common/util/aos_strerror.h
new file mode 100644
index 0000000..2fd6818
--- /dev/null
+++ b/aos/common/util/aos_strerror.h
@@ -0,0 +1,21 @@
+#ifndef AOS_COMMON_UTIL_AOS_STRERROR_H_
+#define AOS_COMMON_UTIL_AOS_STRERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Thread-safe version of strerror(3) (except it may change errno).
+//
+// Necessary because strerror_r(3) is such a mess (which version you get is
+// determined at compile time by black magic related to feature macro
+// definitions, compiler flags, glibc version, and even whether you're using g++
+// or clang++) and strerror_l(3) might not work if you end up with the magic
+// LC_GLOBAL_LOCALE locale.
+char *aos_strerror(int error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // AOS_COMMON_UTIL_AOS_STRERROR_H_
diff --git a/aos/common/util/death_test_log_implementation.h b/aos/common/util/death_test_log_implementation.h
new file mode 100644
index 0000000..c1b12c0
--- /dev/null
+++ b/aos/common/util/death_test_log_implementation.h
@@ -0,0 +1,27 @@
+#ifndef AOS_COMMON_UTIL_DEATH_TEST_LOG_IMPLEMENTATION_H_
+#define AOS_COMMON_UTIL_DEATH_TEST_LOG_IMPLEMENTATION_H_
+
+#include <stdlib.h>
+
+#include "aos/common/logging/logging_impl.h"
+
+namespace aos {
+namespace util {
+
+// Prints all FATAL messages to stderr and then abort(3)s before the regular
+// stuff can print out anything else. Ignores all other messages.
+// This is useful in death tests that expect a LOG(FATAL) to cause the death.
+class DeathTestLogImplementation : public logging::HandleMessageLogImplementation {
+ public:
+  virtual void HandleMessage(const logging::LogMessage &message) override {
+    if (message.level == FATAL) {
+      logging::internal::PrintMessage(stderr, message);
+      abort();
+    }
+  }
+};
+
+}  // namespace util
+}  // namespace aos
+
+#endif  // AOS_COMMON_UTIL_DEATH_TEST_LOG_IMPLEMENTATION_H_
diff --git a/aos/common/util/util.gyp b/aos/common/util/util.gyp
index b20a7d9..9f3e1c6 100644
--- a/aos/common/util/util.gyp
+++ b/aos/common/util/util.gyp
@@ -1,6 +1,26 @@
 {
   'targets': [
     {
+      'target_name': 'death_test_log_implementation',
+      'type': 'static_library',
+      'sources': [
+        #'death_test_log_implementation',
+      ],
+      'dependencies': [
+        '<(AOS)/build/aos.gyp:logging',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/build/aos.gyp:logging',
+      ],
+    },
+    {
+      'target_name': 'aos_strerror',
+      'type': 'static_library',
+      'sources': [
+        'aos_strerror.cc',
+      ],
+    },
+    {
       'target_name': 'inet_addr',
       'type': 'static_library',
       'sources': [
diff --git a/aos/linux_code/configuration.cc b/aos/linux_code/configuration.cc
index 2fd5150..55fff84 100644
--- a/aos/linux_code/configuration.cc
+++ b/aos/linux_code/configuration.cc
@@ -1,7 +1,6 @@
 #include "aos/linux_code/configuration.h"
 
 #include <string.h>
-#include <errno.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <netinet/in.h>
@@ -21,24 +20,24 @@
 // set the IP address when running tests from the test.
 const char *const kLinuxNetInterface = "eth0";
 const in_addr *DoGetOwnIPAddress() {
-    static const char *kOverrideVariable = "FRC971_IP_OVERRIDE";
-    const char *override_ip = getenv(kOverrideVariable);
-    if (override_ip != NULL) {
-        LOG(INFO, "Override IP is %s\n", override_ip);
-        static in_addr r;
-        if (inet_aton(override_ip, &r) != 0) {
-            return &r;
-        } else {
-            LOG(WARNING, "error parsing %s value '%s'\n", kOverrideVariable, override_ip);
-        }
+  static const char *kOverrideVariable = "FRC971_IP_OVERRIDE";
+  const char *override_ip = getenv(kOverrideVariable);
+  if (override_ip != NULL) {
+    LOG(INFO, "Override IP is %s\n", override_ip);
+    static in_addr r;
+    if (inet_aton(override_ip, &r) != 0) {
+      return &r;
     } else {
-        LOG(INFO, "Couldn't get environmental variable.\n");
+      LOG(WARNING, "error parsing %s value '%s'\n",
+          kOverrideVariable, override_ip);
     }
+  } else {
+    LOG(INFO, "Couldn't get environmental variable.\n");
+  }
 
   ifaddrs *addrs;
   if (getifaddrs(&addrs) != 0) {
-    LOG(FATAL, "getifaddrs(%p) failed with %d: %s\n", &addrs,
-        errno, strerror(errno));
+    PLOG(FATAL, "getifaddrs(%p) failed", &addrs);
   }
   // Smart pointers don't work very well for iterating through a linked list,
   // but it does do a very nice job of making sure that addrs gets freed.
@@ -71,8 +70,7 @@
       if (ret != -1) {
         LOG(WARNING, "it returned %zd, not -1\n", ret);
       }
-      LOG(FATAL, "readlink(\"/proc/self/exe\", %p, %zu) failed with %d: %s\n",
-          r, size, errno, strerror(errno));
+      PLOG(FATAL, "readlink(\"/proc/self/exe\", %p, %zu) failed", r, size);
     }
     if (ret < size) {
       void *last_slash = memrchr(r, '/', ret);
diff --git a/aos/linux_code/init.cc b/aos/linux_code/init.cc
index e8bcba1..05004a2 100644
--- a/aos/linux_code/init.cc
+++ b/aos/linux_code/init.cc
@@ -24,15 +24,14 @@
   if (set_for_root || !am_root) {
     struct rlimit64 rlim;
     if (getrlimit64(resource, &rlim) == -1) {
-      Die("%s-init: getrlimit64(%d) failed with %d (%s)\n",
-          program_invocation_short_name, resource, errno, strerror(errno));
+      PDie("%s-init: getrlimit64(%d) failed",
+           program_invocation_short_name, resource);
     }
     rlim.rlim_cur = soft;
     if (setrlimit64(resource, &rlim) == -1) {
-      Die("%s-init: setrlimit64(%d, {cur=%ju,max=%ju})"
-          " failed with %d (%s)\n", program_invocation_short_name,
-          resource, (uintmax_t)rlim.rlim_cur, (uintmax_t)rlim.rlim_max,
-          errno, strerror(errno));
+      PDie("%s-init: setrlimit64(%d, {cur=%ju,max=%ju}) failed",
+           program_invocation_short_name, resource, (uintmax_t)rlim.rlim_cur,
+           (uintmax_t)rlim.rlim_max);
     }
   }
 }
@@ -48,8 +47,7 @@
 int LockAllMemory() {
   InitStart();
   if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
-    Die("%s-init: mlockall failed with %d (%s)\n",
-        program_invocation_short_name, errno, strerror(errno));
+    PDie("%s-init: mlockall failed", program_invocation_short_name);
   }
 
   // Forces the memory pages for all the stack space that we're ever going to
@@ -65,10 +63,7 @@
 // non-realtime processes.
 void DoInitNRT(aos_core_create create) {
   InitStart();
-  if (aos_core_create_shared_mem(create)) {
-    Die("%s-init: creating shared memory reference failed\n",
-        program_invocation_short_name);
-  }
+  aos_core_create_shared_mem(create);
   logging::linux_code::Register();
 }
 
@@ -89,8 +84,7 @@
     struct sched_param param;
     param.sched_priority = 30 + relative_priority;
     if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
-      Die("%s-init: setting SCHED_FIFO failed with %d (%s)\n",
-          program_invocation_short_name, errno, strerror(errno));
+      PDie("%s-init: setting SCHED_FIFO failed", program_invocation_short_name);
     }
   } else {
     fprintf(stderr, "%s not doing realtime initialization because environment"
@@ -103,10 +97,7 @@
 }
 
 void Cleanup() {
-  if (aos_core_free_shared_mem()) {
-    Die("%s-init: freeing shared mem failed\n",
-        program_invocation_short_name);
-  }
+  aos_core_free_shared_mem();
 }
 
 void WriteCoreDumps() {
diff --git a/aos/linux_code/ipc_lib/aos_sync.c b/aos/linux_code/ipc_lib/aos_sync.c
index 2245436..204322f 100644
--- a/aos/linux_code/ipc_lib/aos_sync.c
+++ b/aos/linux_code/ipc_lib/aos_sync.c
@@ -1,6 +1,5 @@
 #include "aos/linux_code/ipc_lib/aos_sync.h"
 
-#include <stdio.h>
 #include <linux/futex.h>
 #include <unistd.h>
 #include <sys/syscall.h>
@@ -10,6 +9,8 @@
 #include <string.h>
 #include <inttypes.h>
 
+#include "aos/common/logging/logging.h"
+
 // TODO(brians): Inline these in the new PI version.
 #define cmpxchg(ptr, o, n) __sync_val_compare_and_swap(ptr, o, n)
 static inline uint32_t xchg(mutex *pointer, uint32_t value) {
@@ -151,31 +152,21 @@
 
 void mutex_unlock(mutex *m) {
   /* Unlock, and if not contended then exit. */
-  //printf("mutex_unlock(%p) => %d \n",m,*m);
   switch (xchg(m, 0)) {
     case 0:
-      fprintf(stderr, "sync: multiple unlock of %p. aborting\n", m);
-      printf("see stderr\n");
-      abort();
+      LOG(FATAL, "multiple unlock of %p\n", m);
     case 1:
-      //printf("mutex_unlock return(%p) => %d \n",m,*m);
       break;
     case 2: {
       const int ret = sys_futex_wake(m, 1);
       if (ret < 0) {
-        fprintf(stderr, "sync: waking 1 from %p failed with %d: %s\n",
-                m, -ret, strerror(-ret));
-        printf("see stderr\n");
-        abort();
+        PELOG(FATAL, -ret, "waking 1 from %p failed", m);
       } else {
         break;
       }
     }
     default:
-      fprintf(stderr, "sync: got a garbage value from mutex %p. aborting\n",
-          m);
-      printf("see stderr\n");
-      abort();
+      LOG(FATAL, "got a garbage value from mutex %p\n", m);
   }
 }
 int mutex_trylock(mutex *m) {
@@ -232,11 +223,8 @@
       if (__builtin_expect(*c == wait_start, 0)) {
         // Try again if it was because of a signal.
         if (ret == -EINTR) continue;
-        fprintf(stderr, "FUTEX_WAIT(%p, %"PRIu32", NULL, NULL, 0) failed"
-                " with %d: %s\n",
-                c, wait_start, -ret, strerror(-ret));
-        printf("see stderr\n");
-        abort();
+        PELOG(FATAL, -ret, "FUTEX_WAIT(%p, %" PRIu32 ", NULL, NULL, 0) failed",
+              c, wait_start);
       }
     }
     // Relock the mutex now that we're done waiting.
@@ -251,11 +239,7 @@
         // Try again if it was because of a signal or somebody else unlocked it
         // before we went to sleep.
         if (ret == -EINTR || ret == -EWOULDBLOCK) continue;
-        fprintf(stderr, "sync: FUTEX_WAIT(%p, 2, NULL, NULL, 0)"
-                " failed with %d: %s\n",
-                m, -ret, strerror(-ret));
-        printf("see stderr\n");
-        abort();
+        PELOG(FATAL, -ret, "FUTEX_WAIT(%p, 2, NULL, NULL, 0) failed", m);
       }
     }
     return;
@@ -270,11 +254,7 @@
   // Wake at most 1 person who is waiting in the kernel.
   const int ret = sys_futex_wake(c, 1);
   if (ret < 0) {
-    fprintf(stderr, "sync: FUTEX_WAKE(%p, 1, NULL, NULL, 0)"
-        " failed with %d: %s\n",
-        c, -ret, strerror(-ret));
-    printf("see stderr\n");
-    abort();
+    PELOG(FATAL, -ret, "FUTEX_WAKE(%p, 1, NULL, NULL, 0) failed", c);
   }
 }
 
@@ -285,10 +265,6 @@
   // mutex anyways.
   const int ret = sys_futex_requeue(c, 1, INT_MAX, m);
   if (ret < 0) {
-    fprintf(stderr, "sync: FUTEX_REQUEUE(%p, 1, INT_MAX, %p, 0)"
-        " failed with %d: %s\n",
-        c, m, -ret, strerror(-ret));
-    printf("see stderr\n");
-    abort();
+    PELOG(FATAL, -ret, "FUTEX_REQUEUE(%p, 1, INT_MAX, %p, 0) failed", c, m);
   }
 }
diff --git a/aos/linux_code/ipc_lib/ipc_lib.gyp b/aos/linux_code/ipc_lib/ipc_lib.gyp
index fe8b2e0..9b1e712 100644
--- a/aos/linux_code/ipc_lib/ipc_lib.gyp
+++ b/aos/linux_code/ipc_lib/ipc_lib.gyp
@@ -6,6 +6,9 @@
       'sources': [
         'aos_sync.c',
       ],
+      'dependencies': [
+        '<(AOS)/build/aos.gyp:logging_interface',
+      ],
     },
     {
       'target_name': 'core_lib',
@@ -29,6 +32,7 @@
       ],
       'dependencies': [
         'aos_sync',
+        '<(AOS)/build/aos.gyp:logging_interface',
       ],
       'export_dependent_settings': [
         'aos_sync',
diff --git a/aos/linux_code/ipc_lib/ipc_stress_test.cc b/aos/linux_code/ipc_lib/ipc_stress_test.cc
index 3067a20..c1dcb83 100644
--- a/aos/linux_code/ipc_lib/ipc_stress_test.cc
+++ b/aos/linux_code/ipc_lib/ipc_stress_test.cc
@@ -82,20 +82,16 @@
 void __attribute__((noreturn)) DoRunTest(
     Shared *shared, const char *(*test)[kTestMaxArgs], int pipes[2]) {
   if (close(pipes[0]) == -1) {
-    Die("close(%d) of read end of pipe failed with %d: %s\n",
-        pipes[0], errno, strerror(errno));
+    PDie("close(%d) of read end of pipe failed", pipes[0]);
   }
   if (close(STDIN_FILENO) == -1) {
-    Die("close(STDIN_FILENO(=%d)) failed with %d: %s\n",
-        STDIN_FILENO, errno, strerror(errno));
+    PDie("close(STDIN_FILENO(=%d)) failed", STDIN_FILENO);
   }
   if (dup2(pipes[1], STDOUT_FILENO) == -1) {
-    Die("dup2(%d, STDOUT_FILENO(=%d)) failed with %d: %s\n",
-        pipes[1], STDOUT_FILENO, errno, strerror(errno));
+    PDie("dup2(%d, STDOUT_FILENO(=%d)) failed", pipes[1], STDOUT_FILENO);
   }
   if (dup2(pipes[1], STDERR_FILENO) == -1) {
-    Die("dup2(%d, STDERR_FILENO(=%d)) failed with %d: %s\n",
-        pipes[1], STDERR_FILENO, errno, strerror(errno));
+    PDie("dup2(%d, STDERR_FILENO(=%d)) failed", pipes[1], STDERR_FILENO);
   }
 
   size_t size = kTestMaxArgs;
@@ -120,8 +116,7 @@
   }
   args[size] = NULL;
   execv(executable.c_str(), const_cast<char *const *>(args));
-  Die("execv(%s, %p) failed with %d: %s\n",
-      executable.c_str(), args, errno, strerror(errno));
+  PDie("execv(%s, %p) failed", executable.c_str(), args);
 }
 
 void DoRun(Shared *shared) {
@@ -133,18 +128,17 @@
   int pipes[2];
   while (time::Time::Now() < shared->stop_time) {
     if (pipe(pipes) == -1) {
-      Die("pipe(%p) failed with %d: %s\n", &pipes, errno, strerror(errno));
+      PDie("pipe(%p) failed", &pipes);
     }
     switch (fork()) {
       case 0:  // in runner
         DoRunTest(shared, test, pipes);
       case -1:
-        Die("fork() failed with %d: %s\n", errno, strerror(errno));
+        PDie("fork() failed");
     }
 
     if (close(pipes[1]) == -1) {
-      Die("close(%d) of write end of pipe failed with %d: %s\n",
-          pipes[1], errno, strerror(errno));
+      PDie("close(%d) of write end of pipe failed", pipes[1]);
     }
 
     ::std::string output;
@@ -153,13 +147,11 @@
       ssize_t ret = read(pipes[0], &buffer, sizeof(buffer));
       if (ret == 0) {  // EOF
         if (close(pipes[0]) == -1) {
-          Die("close(%d) of pipe at EOF failed with %d: %s\n",
-              pipes[0], errno, strerror(errno));
+          PDie("close(%d) of pipe at EOF failed", pipes[0]);
         }
         break;
       } else if (ret == -1) {
-        Die("read(%d, %p, %zd) failed with %d: %s\n",
-            pipes[0], &buffer, sizeof(buffer), errno, strerror(errno));
+        PDie("read(%d, %p, %zd) failed", pipes[0], &buffer, sizeof(buffer));
       }
       output += ::std::string(buffer, ret);
     }
@@ -168,8 +160,7 @@
     while (true) {
       if (wait(&status) == -1) {
         if (errno == EINTR) continue;
-        Die("wait(%p) in child failed with %d: %s\n",
-            &status, errno, strerror(errno));
+        PDie("wait(%p) in child failed", &status);
       } else {
         break;
       }
@@ -207,7 +198,7 @@
       DoRun(shared);
       _exit(EXIT_SUCCESS);
     case -1:
-      Die("fork() of child failed with %d: %s\n", errno, strerror(errno));
+      PDie("fork() of child failed");
   }
 }
 
@@ -222,7 +213,7 @@
   char *temp = strdup(argv[0]);
   if (asprintf(const_cast<char **>(&shared->path),
                "%s/../tests", dirname(temp)) == -1) {
-    Die("asprintf failed with %d: %s\n", errno, strerror(errno));
+    PDie("asprintf failed");
   }
   free(temp);
 
@@ -237,7 +228,7 @@
       if (errno == EINTR) {
         --i;
       } else {
-        Die("wait(%p) failed with %d: %s\n", &status, errno, strerror(errno));
+        PDie("wait(%p) failed", &status);
       }
     }
     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
diff --git a/aos/linux_code/ipc_lib/mutex.cpp b/aos/linux_code/ipc_lib/mutex.cpp
index 47fc92a..8c98204 100644
--- a/aos/linux_code/ipc_lib/mutex.cpp
+++ b/aos/linux_code/ipc_lib/mutex.cpp
@@ -1,7 +1,6 @@
 #include "aos/common/mutex.h"
 
 #include <inttypes.h>
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -20,8 +19,7 @@
 
 void Mutex::Lock() {
   if (mutex_grab(&impl_) != 0) {
-    LOG(FATAL, "mutex_grab(%p(=%" PRIu32 ")) failed because of %d: %s\n",
-        &impl_, impl_, errno, strerror(errno));
+    PLOG(FATAL, "mutex_grab(%p(=%" PRIu32 ")) failed", &impl_, impl_);
   }
 }
 
diff --git a/aos/linux_code/ipc_lib/raw_queue_test.cc b/aos/linux_code/ipc_lib/raw_queue_test.cc
index 67b687a..4196286 100644
--- a/aos/linux_code/ipc_lib/raw_queue_test.cc
+++ b/aos/linux_code/ipc_lib/raw_queue_test.cc
@@ -89,8 +89,7 @@
         if (errno == ESRCH) {
           printf("process %jd was already dead\n", static_cast<intmax_t>(pid_));
         } else {
-          fprintf(stderr, "kill(SIGKILL, %jd) failed with %d: %s\n",
-                  static_cast<intmax_t>(pid_), errno, strerror(errno));
+          PLOG(FATAL, "kill(SIGKILL, %jd) failed", static_cast<intmax_t>(pid_));
         }
         return;
       }
@@ -174,7 +173,7 @@
         mutex_unlock(lock);
         exit(EXIT_SUCCESS);
       case -1:  // parent failure
-        LOG(ERROR, "fork() failed with %d: %s\n", errno, strerror(errno));
+        PLOG(ERROR, "fork() failed");
         return std::unique_ptr<ForkedProcess>();
       default:  // parent
         return std::unique_ptr<ForkedProcess>(new ForkedProcess(pid, lock));
diff --git a/aos/linux_code/ipc_lib/shared_mem.c b/aos/linux_code/ipc_lib/shared_mem.c
index c368e38..a132233 100644
--- a/aos/linux_code/ipc_lib/shared_mem.c
+++ b/aos/linux_code/ipc_lib/shared_mem.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 
 #include "aos/linux_code/ipc_lib/core_lib.h"
+#include "aos/common/logging/logging.h"
 
 // the path for the shared memory segment. see shm_open(3) for restrictions
 #define AOS_SHM_NAME "/aos_shared_mem"
@@ -37,7 +38,7 @@
 struct aos_core *global_core = NULL;
 
 // TODO(brians): madvise(2) it to put this shm in core dumps.
-int aos_core_create_shared_mem(enum aos_core_create to_create) {
+void aos_core_create_shared_mem(enum aos_core_create to_create) {
   static struct aos_core global_core_data;
   global_core = &global_core_data;
 
@@ -59,8 +60,7 @@
       if (shm == -1 && errno == EEXIST) {
         printf("shared_mem: going to shm_unlink(%s)\n", global_core->shm_name);
         if (shm_unlink(global_core->shm_name) == -1) {
-          fprintf(stderr, "shared_mem: shm_unlink(%s) failed with of %d: %s\n",
-                  global_core->shm_name, errno, strerror(errno));
+          PLOG(WARNING, "shm_unlink(%s) failed", global_core->shm_name);
           break;
         }
       } else {
@@ -73,46 +73,35 @@
     global_core->owner = 0;
   }
   if (shm == -1) {
-    fprintf(stderr, "shared_mem:"
-                    " shm_open(%s, O_RDWR [| O_CREAT | O_EXCL, 0|0666)"
-                    " failed with %d: %s\n",
-            global_core->shm_name, errno, strerror(errno));
-    return -1;
+    PLOG(FATAL, "shm_open(%s, O_RDWR [| O_CREAT | O_EXCL, 0|0666) failed",
+         global_core->shm_name);
   }
   if (global_core->owner) {
     if (ftruncate(shm, SIZEOFSHMSEG) == -1) {
-      fprintf(stderr, "shared_mem: fruncate(%d, 0x%zx) failed with %d: %s\n",
-        shm, (size_t)SIZEOFSHMSEG, errno, strerror(errno));
-      return -1;
+      PLOG(FATAL, "fruncate(%d, 0x%zx) failed", shm, (size_t)SIZEOFSHMSEG);
     }
   }
   void *shm_address = mmap(
       (void *)SHM_START, SIZEOFSHMSEG, PROT_READ | PROT_WRITE,
       MAP_SHARED | MAP_FIXED | MAP_LOCKED | MAP_POPULATE, shm, 0);
   if (shm_address == MAP_FAILED) {
-    fprintf(stderr, "shared_mem: mmap(%p, 0x%zx, stuff, stuff, %d, 0) failed"
-            " with %d: %s\n",
-            (void *)SHM_START, (size_t)SIZEOFSHMSEG, shm,
-            errno, strerror(errno));
-    return -1;
+    PLOG(FATAL, "shared_mem: mmap(%p, 0x%zx, stuff, stuff, %d, 0) failed",
+         (void *)SHM_START, (size_t)SIZEOFSHMSEG, shm);
   }
   printf("shared_mem: shm at: %p\n", shm_address);
   if (close(shm) == -1) {
-    printf("shared_mem: close(%d(=shm) failed with %d: %s\n",
-        shm, errno, strerror(errno));
+    PLOG(WARNING, "close(%d(=shm) failed", shm);
   }
   if (shm_address != (void *)SHM_START) {
-    fprintf(stderr, "shared_mem: shm isn't at hard-coded %p. at %p instead\n",
+    LOG(FATAL, "shm isn't at hard-coded %p. at %p instead\n",
         (void *)SHM_START, shm_address);
-    return -1;
   }
-  int r = aos_core_use_address_as_shared_mem(shm_address, SIZEOFSHMSEG);
-  fprintf(stderr, "shared_mem: end of create_shared_mem owner=%d r=%d\n",
-          global_core->owner, r);
-  return r;
+  aos_core_use_address_as_shared_mem(shm_address, SIZEOFSHMSEG);
+  LOG(INFO, "shared_mem: end of create_shared_mem owner=%d\n",
+          global_core->owner);
 }
 
-int aos_core_use_address_as_shared_mem(void *address, size_t size) {
+void aos_core_use_address_as_shared_mem(void *address, size_t size) {
   global_core->mem_struct = address;
   global_core->size = size;
   global_core->shared_mem =
@@ -123,28 +112,22 @@
     futex_set(&global_core->mem_struct->creation_condition);
   } else {
     if (futex_wait(&global_core->mem_struct->creation_condition) != 0) {
-      fprintf(stderr, "waiting on creation_condition failed\n");
-      return -1;
+      LOG(FATAL, "waiting on creation_condition failed\n");
     }
   }
-  return 0;
 }
 
-int aos_core_free_shared_mem(){
+void aos_core_free_shared_mem() {
   void *shm_address = global_core->shared_mem;
-      if (munmap((void *)SHM_START, SIZEOFSHMSEG) == -1) {
-          fprintf(stderr, "shared_mem: munmap(%p, 0x%zx) failed with %d: %s\n",
-        shm_address, (size_t)SIZEOFSHMSEG, errno, strerror(errno));
-          return -1;
-      }
-  if (global_core->owner) {
-        if (shm_unlink(global_core->shm_name)) {
-          fprintf(stderr, "shared_mem: shm_unlink(%s) failed with %d: %s\n",
-                  global_core->shm_name, errno, strerror(errno));
-            return -1;
-        }
+  if (munmap((void *)SHM_START, SIZEOFSHMSEG) == -1) {
+    PLOG(FATAL, "munmap(%p, 0x%zx) failed", shm_address,
+         (size_t)SIZEOFSHMSEG);
   }
-  return 0;
+  if (global_core->owner) {
+    if (shm_unlink(global_core->shm_name)) {
+      PLOG(FATAL, "shared_mem: shm_unlink(%s) failed", global_core->shm_name);
+    }
+  }
 }
 
 int aos_core_is_init(void) {
diff --git a/aos/linux_code/ipc_lib/shared_mem.h b/aos/linux_code/ipc_lib/shared_mem.h
index edab4d0..6968df7 100644
--- a/aos/linux_code/ipc_lib/shared_mem.h
+++ b/aos/linux_code/ipc_lib/shared_mem.h
@@ -66,10 +66,10 @@
 // should be set correctly there.
 // The owner should verify that the first sizeof(mutex) of data is set to 0
 // before passing the memory to this function.
-int aos_core_use_address_as_shared_mem(void *address, size_t size);
+void aos_core_use_address_as_shared_mem(void *address, size_t size);
 
-int aos_core_create_shared_mem(enum aos_core_create to_create);
-int aos_core_free_shared_mem(void);
+void aos_core_create_shared_mem(enum aos_core_create to_create);
+void aos_core_free_shared_mem(void);
 
 // Returns whether or not the shared memory system is active.
 int aos_core_is_init(void);
diff --git a/aos/linux_code/logging/binary_log_file.cc b/aos/linux_code/logging/binary_log_file.cc
index ff3df68..2738c16 100644
--- a/aos/linux_code/logging/binary_log_file.cc
+++ b/aos/linux_code/logging/binary_log_file.cc
@@ -1,7 +1,6 @@
 #include "aos/linux_code/logging/binary_log_file.h"
 
 #include <stdio.h>
-#include <errno.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -43,8 +42,7 @@
 
   struct stat info;
   if (fstat(fd_, &info) == -1) {
-    LOG(FATAL, "fstat(%d, %p) failed with %d: %s\n", fd_, &info, errno,
-        strerror(errno));
+    PLOG(FATAL, "fstat(%d, %p) failed", fd_, &info);
   }
   bool r = offset_ == static_cast<off_t>(info.st_size - kPageSize);
   is_last_page_ = r ? 2 : 1;
@@ -54,32 +52,27 @@
 void LogFileAccessor::MapNextPage() {
   if (writable_) {
     if (ftruncate(fd_, offset_ + kPageSize) == -1) {
-      LOG(FATAL, "ftruncate(%d, %zd) failed with %d: %s. aborting\n", fd_,
-          kPageSize, errno, strerror(errno));
+      PLOG(FATAL, "ftruncate(%d, %zd) failed", fd_, kPageSize);
     }
   }
   current_ = static_cast<char *>(
       mmap(NULL, kPageSize, PROT_READ | (writable_ ? PROT_WRITE : 0),
            MAP_SHARED, fd_, offset_));
   if (current_ == MAP_FAILED) {
-    LOG(FATAL,
-        "mmap(NULL, %zd, PROT_READ [ | PROT_WRITE], MAP_SHARED, %d, %jd)"
-        " failed with %d: %s\n",
-        kPageSize, fd_, static_cast<intmax_t>(offset_), errno,
-        strerror(errno));
+    PLOG(FATAL,
+         "mmap(NULL, %zd, PROT_READ [ | PROT_WRITE], MAP_SHARED, %d, %jd)"
+         " failed", kPageSize, fd_, static_cast<intmax_t>(offset_));
   }
   if (madvise(current_, kPageSize, MADV_SEQUENTIAL | MADV_WILLNEED) == -1) {
-    LOG(WARNING, "madvise(%p, %zd, MADV_SEQUENTIAL | MADV_WILLNEED)"
-                 " failed with %d: %s\n",
-        current_, kPageSize, errno, strerror(errno));
+    PLOG(WARNING, "madvise(%p, %zd, MADV_SEQUENTIAL | MADV_WILLNEED) failed",
+         current_, kPageSize);
   }
   offset_ += kPageSize;
 }
 
 void LogFileAccessor::Unmap(void *location) {
   if (munmap(location, kPageSize) == -1) {
-    LOG(FATAL, "munmap(%p, %zd) failed with %d: %s. aborting\n", location,
-        kPageSize, errno, strerror(errno));
+    PLOG(FATAL, "munmap(%p, %zd) failed", location, kPageSize);
   }
   is_last_page_ = 0;
   position_ = 0;
@@ -137,23 +130,23 @@
     action.sa_flags = SA_RESETHAND | SA_SIGINFO;
     struct sigaction previous_bus, previous_segv;
     if (sigaction(SIGBUS, &action, &previous_bus) == -1) {
-      LOG(FATAL, "sigaction(SIGBUS(=%d), %p, %p) failed with %d: %s\n",
-          SIGBUS, &action, &previous_bus, errno, strerror(errno));
+      PLOG(FATAL, "sigaction(SIGBUS(=%d), %p, %p) failed",
+           SIGBUS, &action, &previous_bus);
     }
     if (sigaction(SIGSEGV, &action, &previous_segv) == -1) {
-      LOG(FATAL, "sigaction(SIGSEGV(=%d), %p, %p) failed with %d: %s\n",
-          SIGSEGV, &action, &previous_segv, errno, strerror(errno));
+      PLOG(FATAL, "sigaction(SIGSEGV(=%d), %p, %p) failed",
+           SIGSEGV, &action, &previous_segv);
     }
 
     char __attribute__((unused)) c = current()[0];
 
     if (sigaction(SIGBUS, &previous_bus, NULL) == -1) {
-      LOG(FATAL, "sigaction(SIGBUS(=%d), %p, NULL) failed with %d: %s\n",
-          SIGBUS, &previous_bus, errno, strerror(errno));
+      PLOG(FATAL, "sigaction(SIGBUS(=%d), %p, NULL) failed",
+           SIGBUS, &previous_bus);
     }
     if (sigaction(SIGSEGV, &previous_segv, NULL) == -1) {
-      LOG(FATAL, "sigaction(SIGSEGV(=%d), %p, NULL) failed with %d: %s\n",
-          SIGSEGV, &previous_segv, errno, strerror(errno));
+      PLOG(FATAL, "sigaction(SIGSEGV(=%d), %p, NULL) failed",
+           SIGSEGV, &previous_segv);
     }
   } else {
     if (fault_address == current()) {
@@ -173,9 +166,8 @@
     MapNextPage();
     if (futex_set_value(static_cast<mutex *>(static_cast<void *>(
                     &temp[position()])), 2) == -1) {
-      LOG(WARNING,
-          "futex_set_value(%p, 2) failed with %d: %s. readers will hang\n",
-          &temp[position()], errno, strerror(errno));
+      PLOG(WARNING, "readers will hang because futex_set_value(%p, 2) failed",
+           &temp[position()]);
     }
     Unmap(temp);
   }
diff --git a/aos/linux_code/logging/binary_log_writer.cc b/aos/linux_code/logging/binary_log_writer.cc
index 37a069b..0013dd4 100644
--- a/aos/linux_code/logging/binary_log_writer.cc
+++ b/aos/linux_code/logging/binary_log_writer.cc
@@ -75,8 +75,7 @@
     }
     closedir(d);
   } else {
-    aos::Die("could not open directory %s because of %d (%s).\n", directory,
-             errno, strerror(errno));
+    PDie("could not open directory %s", directory);
   }
 
   char previous[512];
@@ -90,8 +89,7 @@
     printf("Could not find aos_log-current\n");
   }
   if (asprintf(filename, "%s/aos_log-%03d", directory, fileindex) == -1) {
-    aos::Die("couldn't create final name because of %d (%s)\n",
-             errno, strerror(errno));
+    PDie("couldn't create final name");
   }
   LOG(INFO, "Created log file (aos_log-%d) in directory (%s). Previous file "
             "was (%s).\n",
@@ -114,19 +112,13 @@
   AllocateLogName(&tmp, folder);
   char *tmp2;
   if (asprintf(&tmp2, "%s/aos_log-current", folder) == -1) {
-    fprintf(stderr,
-            "BinaryLogReader: couldn't create symlink name because of %d (%s)."
-            " not creating current symlink\n", errno, strerror(errno));
+    PLOG(WARNING, "couldn't create current symlink name");
   } else {
     if (unlink(tmp2) == -1 && (errno != EROFS && errno != ENOENT)) {
-      fprintf(stderr,
-              "BinaryLogReader: warning: unlink('%s') failed"
-              " because of %d (%s)\n",
-              tmp2, errno, strerror(errno));
+      LOG(WARNING, "unlink('%s') failed", tmp2);
     }
     if (symlink(tmp, tmp2) == -1) {
-      fprintf(stderr, "BinaryLogReader: warning: symlink('%s', '%s') failed"
-              " because of %d (%s)\n", tmp, tmp2, errno, strerror(errno));
+      PLOG(WARNING, "symlink('%s', '%s') failed", tmp, tmp2);
     }
     free(tmp2);
   }
@@ -134,10 +126,7 @@
                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
   free(tmp);
   if (fd == -1) {
-    fprintf(stderr,
-            "BinaryLogReader: couldn't open file '%s' because of %d (%s)."
-            " exiting\n", tmp, errno, strerror(errno));
-    return EXIT_FAILURE;
+    PLOG(FATAL, "opening file '%s' failed", tmp);
   }
   LogFileWriter writer(fd);
 
diff --git a/aos/linux_code/logging/linux_interface.cc b/aos/linux_code/logging/linux_interface.cc
index d039c70..9889c07 100644
--- a/aos/linux_code/logging/linux_interface.cc
+++ b/aos/linux_code/logging/linux_interface.cc
@@ -20,8 +20,7 @@
 
   char thread_name_array[kThreadNameLength + 1];
   if (prctl(PR_GET_NAME, thread_name_array) != 0) {
-    Die("prctl(PR_GET_NAME, %p) failed with %d: %s\n",
-        thread_name_array, errno, strerror(errno));
+    PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
   }
   thread_name_array[sizeof(thread_name_array) - 1] = '\0';
   ::std::string thread_name(thread_name_array);
diff --git a/aos/linux_code/logging/log_displayer.cc b/aos/linux_code/logging/log_displayer.cc
index 0bb3508..071a87e 100644
--- a/aos/linux_code/logging/log_displayer.cc
+++ b/aos/linux_code/logging/log_displayer.cc
@@ -5,7 +5,6 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <inttypes.h>
-#include <errno.h>
 
 #include <algorithm>
 
@@ -146,10 +145,7 @@
 
   int fd = open(filename, O_RDONLY);
   if (fd == -1) {
-    fprintf(stderr,
-            "error: couldn't open file '%s' for reading because of %s\n",
-            filename, strerror(errno));
-    exit(EXIT_FAILURE);
+    PLOG(FATAL, "couldn't open file '%s' for reading", filename);
   }
   ::aos::logging::linux_code::LogFileReader reader(fd);
 
diff --git a/aos/linux_code/output/HTTPServer.cpp b/aos/linux_code/output/HTTPServer.cpp
index 1703d39..d18572b 100644
--- a/aos/linux_code/output/HTTPServer.cpp
+++ b/aos/linux_code/output/HTTPServer.cpp
@@ -5,6 +5,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
+#include <errno.h>
 
 #include <memory>
 
@@ -81,8 +82,8 @@
                    const char *directory) {
   char *temp;
   if (asprintf(&temp, "%s/%s", directory, path) == -1) {
-    LOG(WARNING, "asprintf(%p, \"%%s/%%s\", %p, %p) failed with %d: %s\n",
-        &temp, directory, path, errno, strerror(errno));
+    PLOG(WARNING, "asprintf(%p, \"%%s/%%s\", %p, %p) failed",
+         &temp, directory, path);
     evhttp_send_error(request, HTTP_INTERNAL, NULL);
     return -1;
   }
@@ -93,8 +94,7 @@
       evhttp_send_error(request, HTTP_NOTFOUND, NULL);
       return -1;
     }
-    LOG(ERROR, "open('%s', 0) failed with %d: %s\n", filename.get(),
-        errno, strerror(errno));
+    PLOG(ERROR, "open('%s', 0) failed", filename.get(),
     evhttp_send_error(request, HTTP_INTERNAL, NULL);
     return -1;
   }
@@ -104,8 +104,7 @@
 off_t GetSize(int file) {
   struct stat info;
   if (fstat(file, &info) == -1) {
-    LOG(ERROR, "stat(%d, %p) failed with %d: %s\n", file, &info,
-        errno, strerror(errno));
+    PLOG(ERROR, "stat(%d, %p) failed", file, &info);
     return -1;
   }
   return info.st_size;
diff --git a/aos/linux_code/starter/netconsole.cc b/aos/linux_code/starter/netconsole.cc
index f624673..4d32afe 100644
--- a/aos/linux_code/starter/netconsole.cc
+++ b/aos/linux_code/starter/netconsole.cc
@@ -92,9 +92,8 @@
       }
       if (read_bytes == -1) {
         if (errno != EINTR) {
-          LOG(FATAL, "read(%d, %p, %zd) failed with %d: %s\n",
-              to_copy->input, buffer + position, position - sizeof(buffer),
-              errno, strerror(errno));
+          PLOG(FATAL, "read(%d, %p, %zd) failed",
+               to_copy->input, buffer + position, position - sizeof(buffer));
         }
       } else if (read_bytes == 0 && to_copy->interface_address == NULL) {
         // read(2) says that this means EOF
@@ -111,8 +110,8 @@
       ssize_t sent_bytes = write(to_copy->output, buffer, position);
       if (sent_bytes == -1) {
         if (errno != EINTR) {
-          LOG(FATAL, "write(%d, %p, %zd) failed with %d: %s\n",
-              to_copy->output, buffer, position, errno, strerror(errno));
+          PLOG(FATAL, "write(%d, %p, %zd) failed",
+               to_copy->output, buffer, position);
         }
       } else if (sent_bytes != 0) {
         if (sent_bytes == position) {
@@ -129,6 +128,7 @@
 int NetconsoleMain(int argc, char **argv) {
   WriteCoreDumps();
   logging::Init();
+  logging::AddImplementation(new logging::StreamLogImplementation(stdout));
 
   int input, output;
   if (argc > 1) {
@@ -136,12 +136,9 @@
     if (output == -1) {
       if (errno == EACCES || errno == ELOOP || errno == ENOSPC ||
           errno == ENOTDIR || errno == EROFS || errno == ETXTBSY) {
-        fprintf(stderr, "Opening output file '%s' failed because of %s.\n",
-                argv[1], strerror(errno));
-        exit(EXIT_FAILURE);
+        PLOG(FATAL, "opening output file '%s' failed", argv[1]);
       }
-      LOG(FATAL, "open('%s', stuff, 0644) failed with %d: %s\n", argv[1],
-          errno, strerror(errno));
+      PLOG(FATAL, "open('%s', stuff, 0644) failed", argv[1]);
     }
     fprintf(stderr, "Writing output to '%s'.\n", argv[1]);
     input = -1;
@@ -157,20 +154,16 @@
 
   int from_crio = socket(AF_INET, SOCK_DGRAM, 0);
   if (from_crio == -1) {
-    LOG(FATAL, "socket(AF_INET, SOCK_DGRAM, 0) failed with %d: %s\n",
-        errno, strerror(errno));
+    PLOG(FATAL, "socket(AF_INET, SOCK_DGRAM, 0) failed");
   }
   if (setsockopt(from_crio, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-    LOG(FATAL, "SOL_SOCKET::SO_REUSEADDR=%d(%d) failed with %d: %s\n",
-        on, from_crio, errno, strerror(errno));
+    PLOG(FATAL, "SOL_SOCKET::SO_REUSEADDR=%d(%d) failed", on, from_crio);
   }
   if (setsockopt(from_crio, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
-    LOG(FATAL, "SOL_SOCKET::SO_BROADCAST=%d(%d) failed with %d: %s\n",
-        on, from_crio, errno, strerror(errno));
+    PLOG(FATAL, "SOL_SOCKET::SO_BROADCAST=%d(%d) failed", on, from_crio);
   }
   if (setsockopt(from_crio, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)) == -1) {
-    LOG(FATAL, "IPROTO_IP::IP_PKTINFO=%d(%d) failed with %d: %s\n",
-        on, from_crio, errno, strerror(errno));
+    PLOG(FATAL, "IPROTO_IP::IP_PKTINFO=%d(%d) failed", on, from_crio);
   }
   union {
     struct sockaddr_in in;
@@ -188,8 +181,8 @@
                               ::aos::NetworkAddress::kCRIO);
 
   if (bind(from_crio, &address.addr, sizeof(address)) == -1) {
-    LOG(FATAL, "bind(%d, %p, %zu) failed with %d: %s\n",
-        from_crio, &address.addr, sizeof(address), errno, strerror(errno));
+    PLOG(FATAL, "bind(%d, %p, %zu) failed",
+         from_crio, &address.addr, sizeof(address));
   }
 
   pthread_t input_thread, output_thread;
@@ -202,36 +195,33 @@
   if (input != -1) {
     int to_crio = socket(AF_INET, SOCK_DGRAM, 0);
     if (to_crio == -1) {
-      LOG(FATAL, "socket(AF_INET, SOCK_DGRAM, 0) failed with %d: %s\n",
-          errno, strerror(errno));
+      PLOG(FATAL, "socket(AF_INET, SOCK_DGRAM, 0) failed");
     }
     if (setsockopt(to_crio, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-      LOG(FATAL, "SOL_SOCKET::SO_REUSEADDR=%d(%d) failed with %d: %s\n",
-          on, to_crio, errno, strerror(errno));
+      PLOG(FATAL, "SOL_SOCKET::SO_REUSEADDR=%d(%d) failed", on, to_crio);
     }
     address.in.sin_port = hton<uint16_t>(6668);
     if (connect(to_crio, &address.addr, sizeof(address)) == -1) {
-      LOG(FATAL, "connect(%d, %p, %zu) failed with %d: %s\n",
-          to_crio, &address.addr, sizeof(address), errno, strerror(errno));
+      PLOG(FATAL, "connect(%d, %p, %zu) failed",
+           to_crio, &address.addr, sizeof(address));
     }
     FDsToCopy input_fds{input, to_crio, nullptr, nullptr};
     if (pthread_create(&input_thread, NULL, FDCopyThread, &input_fds) == -1) {
-      LOG(FATAL, "pthread_create(%p, NULL, %p, %p) failed with %d: %s\n",
-          &input_thread, FDCopyThread, &input_fds, errno, strerror(errno));
+      PLOG(FATAL, "pthread_create(%p, NULL, %p, %p) failed",
+           &input_thread, FDCopyThread, &input_fds);
     }
   }
 
   address.in.sin_addr = ::aos::configuration::GetOwnIPAddress();
   FDsToCopy output_fds{from_crio, output, &address.in, &crio_address.in};
   if (pthread_create(&output_thread, NULL, FDCopyThread, &output_fds) == -1) {
-    LOG(FATAL, "pthread_create(%p, NULL, %p, %p) failed with %d: %s\n",
-        &output_thread, FDCopyThread, &output_fds, errno, strerror(errno));
+    PLOG(FATAL, "pthread_create(%p, NULL, %p, %p) failed",
+         &output_thread, FDCopyThread, &output_fds);
   }
 
   // input_thread will finish when stdin gets an EOF
   if (pthread_join((input == -1) ? output_thread : input_thread, NULL) == -1) {
-    LOG(FATAL, "pthread_join(a_thread, NULL) failed with %d: %s\n",
-        errno, strerror(errno));
+    PLOG(FATAL, "pthread_join(a_thread, NULL) failed");
   }
   exit(EXIT_SUCCESS);
 }
diff --git a/aos/linux_code/starter/starter.cc b/aos/linux_code/starter/starter.cc
index 114148f..800acd9 100644
--- a/aos/linux_code/starter/starter.cc
+++ b/aos/linux_code/starter/starter.cc
@@ -112,8 +112,7 @@
     assert(watch_to_remove_ == -1);
 
     if (inotify_rm_watch(notify_fd, watch_) == -1) {
-      LOG(WARNING, "inotify_rm_watch(%d, %d) failed with %d: %s\n",
-          notify_fd, watch_, errno, strerror(errno));
+      PLOG(WARNING, "inotify_rm_watch(%d, %d) failed", notify_fd, watch_);
     }
     watch_to_remove_ = watch_;
     watch_ = -1;
@@ -159,10 +158,9 @@
                                                      IN_DELETE_SELF |
                                                      IN_MOVE_SELF));
     if (watch_ == -1) {
-      LOG(FATAL, "inotify_add_watch(%d, %s,"
-          " %s ? IN_CREATE : (IN_ATTRIB | IN_MODIFY)) failed with %d: %s\n",
-          notify_fd, filename_.c_str(), create_ ? "true" : "false",
-          errno, strerror(errno));
+      PLOG(FATAL, "inotify_add_watch(%d, %s,"
+                  " %s ? IN_CREATE : (IN_ATTRIB | IN_MODIFY)) failed",
+           notify_fd, filename_.c_str(), create_ ? "true" : "false");
     }
     watchers[watch_] = this;
     LOG(DEBUG, "watch for %s is %d\n", filename_.c_str(), watch_);
@@ -174,8 +172,7 @@
     unsigned int to_read;
     // Use FIONREAD to figure out how many bytes there are to read.
     if (ioctl(notify_fd, FIONREAD, &to_read) < 0) {
-      LOG(FATAL, "FIONREAD(%d, %p) failed with %d: %s\n",
-          notify_fd, &to_read, errno, strerror(errno));
+      PLOG(FATAL, "FIONREAD(%d, %p) failed", notify_fd, &to_read);
     }
     inotify_event *notifyevt = static_cast<inotify_event *>(malloc(to_read));
     const char *end = reinterpret_cast<char *>(notifyevt) + to_read;
@@ -183,8 +180,7 @@
 
     ssize_t ret = read(notify_fd, notifyevt, to_read);
     if (ret < 0) {
-      LOG(FATAL, "read(%d, %p, %u) failed with %d: %s\n",
-          notify_fd, notifyevt, to_read, errno, strerror(errno));
+      PLOG(FATAL, "read(%d, %p, %u) failed", notify_fd, notifyevt, to_read);
     }
     if (static_cast<size_t>(ret) != to_read) {
       LOG(ERROR, "read(%d, %p, %u) returned %zd instead of %u\n",
@@ -277,8 +273,7 @@
   errno = 0;
   FILE *pipe = popen(command.c_str(), "r");
   if (pipe == NULL) {
-    LOG(FATAL, "popen(\"%s\", \"r\") failed with %d: %s\n",
-        command.c_str(), errno, strerror(errno));
+    PLOG(FATAL, "popen(\"%s\", \"r\") failed", command.c_str());
   }
 
   // result_size is how many bytes result is currently allocated to.
@@ -290,8 +285,7 @@
       result_size *= 2;
       void *new_result = realloc(result.get(), result_size);
       if (new_result == NULL) {
-        LOG(FATAL, "realloc(%p, %zd) failed because of %d: %s\n",
-            result.get(), result_size, errno, strerror(errno));
+        PLOG(FATAL, "realloc(%p, %zd) failed", result.get(), result_size);
       } else {
         result.release();
         result = unique_c_ptr<char>(static_cast<char *>(new_result));
@@ -303,8 +297,8 @@
     // because of an error.
     if (ret < result_size - read) {
       if (ferror(pipe)) {
-        LOG(FATAL, "couldn't finish reading output of \"%s\"\n",
-            command.c_str());
+        PLOG(FATAL, "couldn't finish reading output of \"%s\"\n",
+             command.c_str());
       }
     }
     read += ret;
@@ -322,8 +316,7 @@
 
   int child_status = pclose(pipe);
   if (child_status == -1) {
-    LOG(FATAL, "pclose(%p) failed with %d: %s\n", pipe,
-        errno, strerror(errno));
+    PLOG(FATAL, "pclose(%p) failed", pipe);
   }
 
   if (child_status != 0) {
@@ -457,8 +450,8 @@
     if (stat_at_start_valid_) {
       struct stat current_stat;
       if (stat(original_binary_.c_str(), &current_stat) == -1) {
-        LOG(FATAL, "stat(%s, %p) failed with %d: %s\n",
-            original_binary_.c_str(), &current_stat, errno, strerror(errno));
+        PLOG(FATAL, "stat(%s, %p) failed",
+             original_binary_.c_str(), &current_stat);
       }
       if (current_stat.st_mtime == stat_at_start_.st_mtime) {
         LOG(DEBUG, "ignoring trigger for %s because mtime didn't change\n",
@@ -474,8 +467,7 @@
     if (pid_ != -1) {
       LOG(DEBUG, "sending SIGTERM to child %d to restart it\n", pid_);
       if (kill(pid_, SIGTERM) == -1) {
-        LOG(WARNING, "kill(%d, SIGTERM) failed with %d: %s\n",
-            pid_, errno, strerror(errno));
+        PLOG(WARNING, "kill(%d, SIGTERM) failed", pid_);
       }
       CheckDiedStatus *status = new CheckDiedStatus();
       status->self = this;
@@ -497,8 +489,7 @@
     if (pid_ == old_pid) {
       LOG(WARNING, "child %d refused to die\n", old_pid);
       if (kill(old_pid, SIGKILL) == -1) {
-        LOG(WARNING, "kill(%d, SIGKILL) failed with %d: %s\n",
-            old_pid, errno, strerror(errno));
+        PLOG(WARNING, "kill(%d, SIGKILL) failed", old_pid);
       }
     }
   }
@@ -513,8 +504,7 @@
       LOG(WARNING, "calling Start() but already have child %d running\n",
           pid_);
       if (kill(pid_, SIGKILL) == -1) {
-        LOG(WARNING, "kill(%d, SIGKILL) failed with %d: %s\n",
-            pid_, errno, strerror(errno));
+        PLOG(WARNING, "kill(%d, SIGKILL) failed", pid_);
         return;
       }
       pid_ = -1;
@@ -523,17 +513,16 @@
     // Remove the name that we run from (ie from a previous execution) and then
     // hard link the real filename to it.
     if (unlink(binary_.c_str()) != 0 && errno != ENOENT) {
-      LOG(FATAL, "removing %s failed because of %d: %s\n",
-          binary_.c_str(), errno, strerror(errno));
+      PLOG(FATAL, "removing %s failed", binary_.c_str());
     }
     if (link(original_binary_.c_str(), binary_.c_str()) != 0) {
-      LOG(FATAL, "link('%s', '%s') failed because of %d: %s\n",
-          original_binary_.c_str(), binary_.c_str(), errno, strerror(errno));
+      PLOG(FATAL, "link('%s', '%s') failed",
+           original_binary_.c_str(), binary_.c_str());
     }
 
     if (stat(original_binary_.c_str(), &stat_at_start_) == -1) {
-      LOG(FATAL, "stat(%s, %p) failed with %d: %s\n",
-          original_binary_.c_str(), &stat_at_start_, errno, strerror(errno));
+      PLOG(FATAL, "stat(%s, %p) failed",
+           original_binary_.c_str(), &stat_at_start_);
     }
     stat_at_start_valid_ = true;
 
@@ -547,13 +536,11 @@
       // The const_cast is safe because no code that might care if it gets
       // modified can run afterwards.
       execv(binary_.c_str(), const_cast<char **>(argv));
-      LOG(FATAL, "execv(%s, %p) failed with %d: %s\n",
-          binary_.c_str(), argv, errno, strerror(errno));
+      PLOG(FATAL, "execv(%s, %p) failed", binary_.c_str(), argv);
       _exit(EXIT_FAILURE);
     }
     if (pid_ == -1) {
-      LOG(FATAL, "forking to run \"%s\" failed with %d: %s\n",
-          binary_.c_str(), errno, strerror(errno));
+      PLOG(FATAL, "forking to run \"%s\" failed", binary_.c_str());
     }
     LOG(DEBUG, "started \"%s\" successfully\n", binary_.c_str());
   }
@@ -657,7 +644,7 @@
     siginfo_t infop;
     infop.si_pid = 0;
     if (waitid(P_ALL, 0, &infop, WEXITED | WSTOPPED | WNOHANG) != 0) {
-      LOG(WARNING, "waitid failed with %d: %s", errno, strerror(errno));
+      PLOG(WARNING, "waitid failed");
       continue;
     }
     // If there are no more child process deaths to process.
@@ -720,7 +707,7 @@
   // bring up shm is ok
 
   if (setpgid(0 /*self*/, 0 /*make PGID the same as PID*/) != 0) {
-    LOG(FATAL, "setpgid(0, 0) failed with %d: %s\n", errno, strerror(errno));
+    PLOG(FATAL, "setpgid(0, 0) failed");
   }
 
   // Make sure that we kill all children when we exit.
@@ -745,7 +732,7 @@
   core_touch_file += std::to_string(static_cast<intmax_t>(getpid()));
   core_touch_file += ".core_touch_file";
   if (system(("touch '" + core_touch_file + "'").c_str()) != 0) {
-    LOG(FATAL, "running `touch '%s'` failed\n", core_touch_file.c_str());
+    PLOG(FATAL, "running `touch '%s'` failed\n", core_touch_file.c_str());
   }
   FileWatch core_touch_file_watch(core_touch_file, Run, NULL);
   core = unique_ptr<Child>(
@@ -753,12 +740,11 @@
 
   FILE *pid_file = fopen("/tmp/starter.pid", "w");
   if (pid_file == NULL) {
-    LOG(FATAL, "fopen(\"/tmp/starter.pid\", \"w\") failed with %d: %s\n",
-        errno, strerror(errno));
+    PLOG(FATAL, "fopen(\"/tmp/starter.pid\", \"w\") failed");
   } else {
     if (fprintf(pid_file, "%d", core->pid()) == -1) {
-      LOG(WARNING, "fprintf(%p, \"%%d\", %d) failed with %d: %s\n",
-          pid_file, core->pid(), errno, strerror(errno));
+      PLOG(WARNING, "fprintf(%p, \"%%d\", %d) failed",
+           pid_file, core->pid());
     }
     fclose(pid_file);
   }
diff --git a/aos/prime/input/joystick_input.cc b/aos/prime/input/joystick_input.cc
index 9600b78..6a6606e 100644
--- a/aos/prime/input/joystick_input.cc
+++ b/aos/prime/input/joystick_input.cc
@@ -32,8 +32,7 @@
     } else {
       int received = sock.Receive(buffer, sizeof(buffer));
       if (received == -1) {
-        LOG(WARNING, "socket receive failed with %d: %s\n",
-            errno, strerror(errno));
+        PLOG(WARNING, "socket receive failed")
         continue;
       }
 
diff --git a/bbb_cape/src/flasher/stm32_flasher.cc b/bbb_cape/src/flasher/stm32_flasher.cc
index a48abc4..d9d87fe 100644
--- a/bbb_cape/src/flasher/stm32_flasher.cc
+++ b/bbb_cape/src/flasher/stm32_flasher.cc
@@ -60,8 +60,7 @@
     filename = target;
     file = open(filename.c_str(), O_RDONLY);
     if (file == -1) {
-      LOG(FATAL, "open(%s, O_RDONLY) failed with %d: %s\n",
-          filename.c_str(), errno, strerror(errno));
+      PLOG(FATAL, "open(%s, O_RDONLY) failed", filename.c_str());
     } else {
       LOG(INFO, "using filename %s from the command line\n", filename.c_str());
     }
@@ -73,8 +72,7 @@
         2 /* record type */];
     ssize_t bytes = read(file, buffer, sizeof(buffer));
     if (close(file) == -1) {
-      LOG(FATAL, "close(%d) failed with %d: %s\n",
-          file, errno, strerror(errno));
+      PLOG(FATAL, "close(%d) failed", file);
     }
     if (bytes != sizeof(buffer)) {
       LOG(FATAL, "read %zd bytes from %s instead of %zu\n",
@@ -107,7 +105,7 @@
     LOG(FATAL, "%s parser failed to initialize.\n", parser->name);
   }
   if (parser->open(p_st, filename.c_str(), 0) != PARSER_ERR_OK) {
-    LOG(FATAL, "opening file %s failed\n", filename.c_str());
+    PLOG(FATAL, "opening file %s failed\n", filename.c_str());
   }
 
   ::bbb::ExportUart();
@@ -116,15 +114,13 @@
 
   serial_t *serial = serial_open(device);
   if (serial == NULL) {
-    LOG(FATAL, "failed to open serial port %s because of %d: %s\n",
-        device, errno, strerror(errno));
+    PLOG(FATAL, "failed to open serial port %s", device);
   }
   if (serial_setup(serial, baud_rate,
                    SERIAL_BITS_8,
                    SERIAL_PARITY_EVEN,
                    SERIAL_STOPBIT_1) != SERIAL_ERR_OK) {
-    LOG(FATAL, "setting up serial port %s failed because of %d: %s\n",
-        device, errno, strerror(errno));
+    PLOG(FATAL, "setting up serial port %s failed", device);
   }
   LOG(INFO, "serial configuration: %s\n", serial_get_setup_str(serial));
 
diff --git a/frc971/actions/action.h b/frc971/actions/action.h
index 591aac1..1fc50ea 100644
--- a/frc971/actions/action.h
+++ b/frc971/actions/action.h
@@ -7,7 +7,6 @@
 #include <functional>
 
 #include "aos/common/logging/logging.h"
-#include "aos/common/network/team_number.h"
 #include "aos/common/time.h"
 
 #include "frc971/constants.h"
diff --git a/frc971/actions/actions.gyp b/frc971/actions/actions.gyp
index d2eb82f..0ddd61c 100644
--- a/frc971/actions/actions.gyp
+++ b/frc971/actions/actions.gyp
@@ -140,13 +140,11 @@
       ],
       'dependencies': [
         '<(AOS)/build/aos.gyp:logging',
-        '<(AOS)/common/network/network.gyp:team_number',
         '<(DEPTH)/frc971/frc971.gyp:constants',
         '<(AOS)/common/common.gyp:time',
       ],
       'export_dependent_settings': [
         '<(AOS)/build/aos.gyp:logging',
-        '<(AOS)/common/network/network.gyp:team_number',
         '<(DEPTH)/frc971/frc971.gyp:constants',
         '<(AOS)/common/common.gyp:time',
       ],
diff --git a/frc971/autonomous/auto.cc b/frc971/autonomous/auto.cc
index 5a4b4a1..7c9473c 100644
--- a/frc971/autonomous/auto.cc
+++ b/frc971/autonomous/auto.cc
@@ -6,7 +6,6 @@
 #include "aos/common/time.h"
 #include "aos/common/util/trapezoid_profile.h"
 #include "aos/common/logging/logging.h"
-#include "aos/common/network/team_number.h"
 #include "aos/common/logging/queue_logging.h"
 
 #include "frc971/autonomous/auto.q.h"
diff --git a/frc971/input/hot_goal_reader.cc b/frc971/input/hot_goal_reader.cc
index 4bf5198..cf05a6a 100644
--- a/frc971/input/hot_goal_reader.cc
+++ b/frc971/input/hot_goal_reader.cc
@@ -32,8 +32,7 @@
     if (my_socket == -1) {
       my_socket = socket(AF_INET, SOCK_STREAM, 0);
       if (my_socket == -1) {
-        LOG(WARNING, "socket(AF_INET, SOCK_STREAM, 0) failed with %d: %s\n",
-            errno, strerror(errno));
+        PLOG(WARNING, "socket(AF_INET, SOCK_STREAM, 0) failed");
         continue;
       } else {
         LOG(INFO, "opened socket (is %d)\n", my_socket);
@@ -45,16 +44,15 @@
         sockaddr_pointer = &address;
         memcpy(&address_pointer, &sockaddr_pointer, sizeof(void *));
         if (bind(my_socket, address_pointer, sizeof(address)) == -1) {
-          LOG(WARNING, "bind(%d, %p, %zu) failed with %d: %s\n",
-              my_socket, &address, sizeof(address), errno, strerror(errno));
+          PLOG(WARNING, "bind(%d, %p, %zu) failed",
+               my_socket, &address, sizeof(address));
           close(my_socket);
           my_socket = -1;
           continue;
         }
 
         if (listen(my_socket, 1) == -1) {
-          LOG(WARNING, "listen(%d, 1) failed with %d: %s\n",
-              my_socket, errno, strerror(errno));
+          PLOG(WARNING, "listen(%d, 1) failed", my_socket);
           close(my_socket);
           my_socket = -1;
           continue;
@@ -64,8 +62,7 @@
 
     int connection = accept4(my_socket, nullptr, nullptr, SOCK_NONBLOCK);
     if (connection == -1) {
-      LOG(WARNING, "accept(%d, nullptr, nullptr) failed with %d: %s\n",
-          my_socket, errno, strerror(errno));
+      PLOG(WARNING, "accept(%d, nullptr, nullptr) failed", my_socket);
       continue;
     }
     LOG(INFO, "accepted (is %d)\n", connection);
@@ -100,9 +97,9 @@
           connection = -1;
           break;
         default:
-          LOG(FATAL,
-              "select(%d, %p, nullptr, nullptr, %p) failed with %d: %s\n",
-              connection + 1, &fds, &timeout_timeval, errno, strerror(errno));
+          PLOG(FATAL,
+               "select(%d, %p, nullptr, nullptr, %p) failed",
+               connection + 1, &fds, &timeout_timeval);
       }
     }
   }