Bug 1572238 - Dump assertion stacks using __android_log_print. r=Ehsan

Defines an android-only version of nsTraceRefcnt::WalkTheStack that takes a function callback, which outputs the stack frame buffer to `__android_log_print`. Also uses `__wrap_dladdr` in MozDescribeCodeAddress, which outputs slightly more informative data for the stack trace (instead of instances of '???/??? [???]').

Differential Revision: https://phabricator.services.mozilla.com/D46868

--HG--
extra : moz-landing-system : lando
This commit is contained in:
kriswright 2019-09-24 12:14:24 +00:00
parent 401c1780fa
commit 9ac396cf78
5 changed files with 43 additions and 0 deletions

View File

@ -21,6 +21,8 @@
#include "mozilla/Types.h"
#ifdef MOZ_DUMP_ASSERTION_STACK
# include "nsTraceRefcnt.h"
# include "mozilla/StackWalk.h"
# include <algorithm>
#endif
/*
@ -161,6 +163,21 @@ MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename,
__android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
"Assertion failure: %s, at %s:%d\n", aStr, aFilename,
aLine);
# if defined(MOZ_DUMP_ASSERTION_STACK)
nsTraceRefcnt::WalkTheStack(
[](uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure) {
MozCodeAddressDetails details;
static const size_t buflen = 1024;
char buf[buflen + 1]; // 1 for trailing '\n'
MozDescribeCodeAddress(aPC, &details);
MozFormatCodeAddressDetails(buf, buflen, aFrameNumber, aPC, &details);
size_t len = std::min(strlen(buf), buflen + 1 - 2);
buf[len++] = '\n';
buf[len] = '\0';
__android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", "%s", buf);
});
# endif
#else
fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine);
# if defined(MOZ_DUMP_ASSERTION_STACK)

View File

@ -14,6 +14,11 @@
#include <string.h>
#if defined(ANDROID) && defined(MOZ_LINKER)
# include "ElfLoader.h"
# include <android/log.h>
#endif
using namespace mozilla;
// for _Unwind_Backtrace from libcxxrt or libunwind
@ -799,7 +804,13 @@ bool MFBT_API MozDescribeCodeAddress(void* aPC,
aDetails->foffset = 0;
Dl_info info;
# if defined(ANDROID) && defined(MOZ_LINKER)
int ok = __wrap_dladdr(aPC, &info);
# else
int ok = dladdr(aPC, &info);
# endif
if (!ok) {
return true;
}

View File

@ -82,6 +82,11 @@ else:
'Mutex_posix.cpp',
]
if CONFIG['MOZ_LINKER']:
LOCAL_INCLUDES += [
'/mozglue/linker',
]
SOURCES += [
'decimal/Decimal.cpp',
]

View File

@ -762,6 +762,13 @@ void nsTraceRefcnt::WalkTheStack(FILE* aStream) {
MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream);
}
#ifdef ANDROID
void nsTraceRefcnt::WalkTheStack(void (*aWriter)(uint32_t, void*, void*,
void*)) {
MozStackWalk(aWriter, /* skipFrames */ 2, /* maxFrames */ 0, nullptr);
}
#endif
/**
* This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache
* the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being

View File

@ -18,6 +18,9 @@ class nsTraceRefcnt {
static void ResetStatistics();
static void WalkTheStack(FILE* aStream);
#ifdef ANDROID
static void WalkTheStack(void (*aWriter)(uint32_t, void*, void*, void*));
#endif
/**
* Tell nsTraceRefcnt whether refcounting, allocation, and destruction