Bug 945504 - Include JS stack in sandbox reporter logs. r=kang

This commit is contained in:
Jed Davis 2014-02-07 10:46:38 -05:00
parent 15a84a312d
commit ebe6274bbf

View File

@ -14,6 +14,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/NullPtr.h"
#include "mozilla/unused.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
@ -25,6 +26,10 @@
#endif
#include "seccomp_filter.h"
#include "mozilla/dom/Exceptions.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "linux_seccomp.h"
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1
@ -57,6 +62,47 @@ struct sock_fprog seccomp_prog = {
seccomp_filter,
};
/**
* Log JS stack info in the same place as the sandbox violation
* message. Useful in case the responsible code is JS and all we have
* are logs and a minidump with the C++ stacks (e.g., on TBPL).
*/
static void
SandboxLogJSStack(void)
{
if (!NS_IsMainThread()) {
// This might be a worker thread... or it might be a non-JS
// thread, or a non-NSPR thread. There's isn't a good API for
// dealing with this, yet.
return;
}
nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
for (int i = 0; frame != nullptr; ++i) {
nsAutoCString fileName, funName;
int32_t lineNumber;
// Don't stop unwinding if an attribute can't be read.
fileName.SetIsVoid(true);
unused << frame->GetFilename(fileName);
lineNumber = 0;
unused << frame->GetLineNumber(&lineNumber);
funName.SetIsVoid(true);
unused << frame->GetName(funName);
if (!funName.IsVoid() || !fileName.IsVoid()) {
LOG_ERROR("JS frame %d: %s %s line %d", i,
funName.IsVoid() ? "(anonymous)" : funName.get(),
fileName.IsVoid() ? "(no file)" : fileName.get(),
lineNumber);
}
nsCOMPtr<nsIStackFrame> nextFrame;
nsresult rv = frame->GetCaller(getter_AddRefs(nextFrame));
NS_ENSURE_SUCCESS_VOID(rv);
frame = nextFrame;
}
}
/**
* This is the SIGSYS handler function. It is used to report to the user
* which system call has been denied by Seccomp.
@ -103,6 +149,9 @@ Reporter(int nr, siginfo_t *info, void *void_context)
}
#endif
// Do this last, in case it crashes or deadlocks.
SandboxLogJSStack();
// Try to reraise, so the parent sees that this process crashed.
// (If tgkill is forbidden, then seccomp will raise SIGSYS, which
// also accomplishes that goal.)