Commit c5d67deb authored by Kenton Varda's avatar Kenton Varda

Merge branch 'master' of github.com:kentonv/capnproto

parents 20f27660 f536c8cf
...@@ -33,7 +33,7 @@ clean-local: ...@@ -33,7 +33,7 @@ clean-local:
cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \ cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \
fi fi
AM_CXXFLAGS = -I$(srcdir)/src -I$(builddir)/src $(PTHREAD_CFLAGS) AM_CXXFLAGS = -I$(srcdir)/src -I$(builddir)/src -DCAPNP_INCLUDE_DIR='"$(includedir)"' $(PTHREAD_CFLAGS)
AM_LDFLAGS = $(PTHREAD_CFLAGS) AM_LDFLAGS = $(PTHREAD_CFLAGS)
......
...@@ -281,6 +281,9 @@ public: ...@@ -281,6 +281,9 @@ public:
if (addStandardImportPaths) { if (addStandardImportPaths) {
loader.addImportPath(kj::heapString("/usr/local/include")); loader.addImportPath(kj::heapString("/usr/local/include"));
loader.addImportPath(kj::heapString("/usr/include")); loader.addImportPath(kj::heapString("/usr/include"));
#ifdef CAPNP_INCLUDE_DIR
loader.addImportPath(kj::heapString(CAPNP_INCLUDE_DIR));
#endif
addStandardImportPaths = false; addStandardImportPaths = false;
} }
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <execinfo.h> #include <execinfo.h>
#endif #endif
#if __linux__ && defined(KJ_DEBUG) #if (__linux__ || __APPLE__) && defined(KJ_DEBUG)
#include <stdio.h> #include <stdio.h>
#include <pthread.h> #include <pthread.h>
#endif #endif
...@@ -42,11 +42,11 @@ namespace kj { ...@@ -42,11 +42,11 @@ namespace kj {
namespace { namespace {
String getStackSymbols(ArrayPtr<void* const> trace) { String getStackSymbols(ArrayPtr<void* const> trace) {
#if __linux__ && defined(KJ_DEBUG) #if (__linux__ || __APPLE__) && defined(KJ_DEBUG)
// We want to generate a human-readable stack trace. // We want to generate a human-readable stack trace.
// TODO(someday): It would be really great if we could avoid farming out to addr2line and do // TODO(someday): It would be really great if we could avoid farming out to another process
// this all in-process, but that may involve onerous requirements like large library // and do this all in-process, but that may involve onerous requirements like large library
// dependencies or using -rdynamic. // dependencies or using -rdynamic.
// The environment manipulation is not thread-safe, so lock a mutex. This could still be // The environment manipulation is not thread-safe, so lock a mutex. This could still be
...@@ -55,15 +55,21 @@ String getStackSymbols(ArrayPtr<void* const> trace) { ...@@ -55,15 +55,21 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
// is in use. // is in use.
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
KJ_DEFER(pthread_mutex_unlock(&mutex));
// Don't heapcheck / intercept syscalls for addr2line. // Don't heapcheck / intercept syscalls.
const char* preload = getenv("LD_PRELOAD"); const char* preload = getenv("LD_PRELOAD");
String oldPreload; String oldPreload;
if (preload != nullptr) { if (preload != nullptr) {
oldPreload = heapString(preload); oldPreload = heapString(preload);
unsetenv("LD_PRELOAD"); unsetenv("LD_PRELOAD");
} }
KJ_DEFER(if (oldPreload != nullptr) { setenv("LD_PRELOAD", oldPreload.cStr(), true); });
String lines[8];
FILE* p = nullptr;
#if __linux__
// Get executable name from /proc/self/exe, then pass it and the stack trace to addr2line to // Get executable name from /proc/self/exe, then pass it and the stack trace to addr2line to
// get file/line pairs. // get file/line pairs.
char exe[512]; char exe[512];
...@@ -73,9 +79,13 @@ String getStackSymbols(ArrayPtr<void* const> trace) { ...@@ -73,9 +79,13 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
} }
exe[n] = '\0'; exe[n] = '\0';
String lines[8]; p = popen(str("addr2line -e ", exe, ' ', strArray(trace, " ")).cStr(), "r");
#elif __APPLE__
// The Mac OS X equivalent of addr2line is atos.
// (Internally, it uses the private CoreSymbolication.framework library.)
p = popen(str("atos -d -p ", getpid(), ' ', strArray(trace, " ")).cStr(), "r");
#endif
FILE* p = popen(str("addr2line -e ", exe, ' ', strArray(trace, " ")).cStr(), "r");
if (p == nullptr) { if (p == nullptr) {
return nullptr; return nullptr;
} }
...@@ -84,10 +94,13 @@ String getStackSymbols(ArrayPtr<void* const> trace) { ...@@ -84,10 +94,13 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
size_t i = 0; size_t i = 0;
while (i < kj::size(lines) && fgets(line, sizeof(line), p) != nullptr) { while (i < kj::size(lines) && fgets(line, sizeof(line), p) != nullptr) {
// Don't include exception-handling infrastructure in stack trace. // Don't include exception-handling infrastructure in stack trace.
// addr2line output matches file names; atos output matches symbol names.
if (i == 0 && if (i == 0 &&
(strstr(line, "kj/common.c++") != nullptr || (strstr(line, "kj/common.c++") != nullptr ||
strstr(line, "kj/exception.") != nullptr || strstr(line, "kj/exception.") != nullptr ||
strstr(line, "kj/debug.") != nullptr)) { strstr(line, "kj/debug.") != nullptr ||
strstr(line, "kj::Exception") != nullptr ||
strstr(line, "kj::_::Debug") != nullptr)) {
continue; continue;
} }
...@@ -101,12 +114,6 @@ String getStackSymbols(ArrayPtr<void* const> trace) { ...@@ -101,12 +114,6 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
pclose(p); pclose(p);
if (oldPreload != nullptr) {
setenv("LD_PRELOAD", oldPreload.cStr(), true);
}
pthread_mutex_unlock(&mutex);
return strArray(arrayPtr(lines, i), ""); return strArray(arrayPtr(lines, i), "");
#else #else
return nullptr; return nullptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment