Bug 1407693 - Part 2 - when a child process crashes, write extra annotation data to a pre-opened file descriptor instead of creating a new file; r=gsvelto,rbarker

This removes the need for the content process to have permissions to create new
files on macOS, allowing more aggressive sandboxing.

MozReview-Commit-ID: 8agL5jwxDSL

--HG--
extra : rebase_source : 17ebcef3e9d24f3d4e7515e3fae95e65cef76a79
This commit is contained in:
Alex Gaynor 2017-11-27 14:37:34 -06:00
Родитель 0d04153faf
Коммит de20b74dc4
16 изменённых файлов: 237 добавлений и 159 удалений

Просмотреть файл

@ -63,6 +63,7 @@
#include "nsHashKeys.h"
#include "nsNativeCharsetUtils.h"
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
#include "private/pprio.h"
using mozilla::MonitorAutoLock;
using mozilla::ipc::GeckoChildProcessHost;
@ -122,6 +123,16 @@ GeckoChildProcessHost::~GeckoChildProcessHost()
if (mChildTask != MACH_PORT_NULL)
mach_port_deallocate(mach_task_self(), mChildTask);
#endif
if (mChildProcessHandle != 0) {
#if defined(XP_WIN)
CrashReporter::DeregisterChildCrashAnnotationFileDescriptor(
base::GetProcId(mChildProcessHandle));
#else
CrashReporter::DeregisterChildCrashAnnotationFileDescriptor(
mChildProcessHandle);
#endif
}
}
//static
@ -621,6 +632,12 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
const char* const childProcessType =
XRE_ChildProcessTypeToString(mProcessType);
PRFileDesc* crashAnnotationReadPipe;
PRFileDesc* crashAnnotationWritePipe;
if (PR_CreatePipe(&crashAnnotationReadPipe, &crashAnnotationWritePipe) != PR_SUCCESS) {
return false;
}
//--------------------------------------------------
#if defined(OS_POSIX)
// For POSIX, we have to be extremely anal about *not* using
@ -769,6 +786,10 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
#endif // defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
}
int fd = PR_FileDesc2NativeHandle(crashAnnotationWritePipe);
mLaunchOptions->fds_to_remap.push_back(
std::make_pair(fd, CrashReporter::GetAnnotationTimeCrashFd()));
# ifdef MOZ_WIDGET_COCOA
// Add a mach port to the command line so the child can communicate its
// 'task_t' back to the parent.
@ -1007,6 +1028,14 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
cmdLine.AppendLooseValue(
UTF8ToWide(CrashReporter::GetChildNotificationPipe()));
PROsfd h = PR_FileDesc2NativeHandle(crashAnnotationWritePipe);
# if defined(MOZ_SANDBOX)
mSandboxBroker.AddHandleToShare(reinterpret_cast<HANDLE>(h));
# endif // defined(MOZ_SANDBOX)
mLaunchOptions->handles_to_inherit.push_back(reinterpret_cast<HANDLE>(h));
std::string hStr = std::to_string(h);
cmdLine.AppendLooseValue(UTF8ToWide(hStr));
// Process type
cmdLine.AppendLooseValue(UTF8ToWide(childProcessType));
@ -1069,6 +1098,15 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
) {
MOZ_CRASH("cannot open handle to child process");
}
#if defined(XP_WIN)
CrashReporter::RegisterChildCrashAnnotationFileDescriptor(
base::GetProcId(process), crashAnnotationReadPipe);
#else
CrashReporter::RegisterChildCrashAnnotationFileDescriptor(process,
crashAnnotationReadPipe);
#endif
PR_Close(crashAnnotationWritePipe);
MonitorAutoLock lock(mMonitor);
mProcessState = PROCESS_CREATED;
lock.Notify();
@ -1140,7 +1178,7 @@ GeckoChildProcessHost::LaunchAndroidService(const char* type,
const base::file_handle_mapping_vector& fds_to_remap,
ProcessHandle* process_handle)
{
MOZ_ASSERT((fds_to_remap.size() > 0) && (fds_to_remap.size() <= 2));
MOZ_ASSERT((fds_to_remap.size() > 0) && (fds_to_remap.size() <= 3));
JNIEnv* const env = mozilla::jni::GetEnvForThread();
MOZ_ASSERT(env);
@ -1154,7 +1192,8 @@ GeckoChildProcessHost::LaunchAndroidService(const char* type,
it++;
// If the Crash Reporter is disabled, there will not be a second file descriptor.
int32_t crashFd = (it != fds_to_remap.end()) ? it->first : -1;
int32_t handle = java::GeckoProcessManager::Start(type, jargs, crashFd, ipcFd);
int32_t crashAnnotationFd = (it != fds_to_remap.end()) ? it->first : -1;
int32_t handle = java::GeckoProcessManager::Start(type, jargs, crashFd, ipcFd, crashAnnotationFd);
if (process_handle) {
*process_handle = handle;

Просмотреть файл

@ -10,5 +10,5 @@ import android.os.ParcelFileDescriptor;
interface IChildProcess {
int getPid();
boolean start(in IProcessManager procMan, in String[] args, in ParcelFileDescriptor crashReporterPfd, in ParcelFileDescriptor ipcPfd);
boolean start(in IProcessManager procMan, in String[] args, in ParcelFileDescriptor crashReporterPfd, in ParcelFileDescriptor ipcPfd, in ParcelFileDescriptor crashAnnotationPfd);
}

Просмотреть файл

@ -127,6 +127,7 @@ public class GeckoThread extends Thread {
// Child process parameters
private int mCrashFileDescriptor = -1;
private int mIPCFileDescriptor = -1;
private int mCrashAnnotationFileDescriptor = -1;
GeckoThread() {
setName("Gecko");
@ -139,7 +140,8 @@ public class GeckoThread extends Thread {
private synchronized boolean init(final GeckoProfile profile, final String[] args,
final String extraArgs, final int flags,
final int crashFd, final int ipcFd) {
final int crashFd, final int ipcFd,
final int crashAnnotationFd) {
ThreadUtils.assertOnUiThread();
uiThreadId = android.os.Process.myTid();
@ -153,6 +155,7 @@ public class GeckoThread extends Thread {
mFlags = flags;
mCrashFileDescriptor = crashFd;
mIPCFileDescriptor = ipcFd;
mCrashAnnotationFileDescriptor = crashAnnotationFd;
mInitialized = true;
notifyAll();
@ -162,13 +165,15 @@ public class GeckoThread extends Thread {
public static boolean initMainProcess(final GeckoProfile profile, final String extraArgs,
final int flags) {
return INSTANCE.init(profile, /* args */ null, extraArgs, flags,
/* crashFd */ -1, /* ipcFd */ -1);
/* crashFd */ -1, /* ipcFd */ -1,
/* crashAnnotationFd */ -1);
}
public static boolean initChildProcess(final String[] args, final int crashFd,
final int ipcFd) {
final int ipcFd,
final int crashAnnotationFd) {
return INSTANCE.init(/* profile */ null, args, /* extraArgs */ null,
/* flags */ 0, crashFd, ipcFd);
/* flags */ 0, crashFd, ipcFd, crashAnnotationFd);
}
private static boolean canUseProfile(final Context context, final GeckoProfile profile,
@ -404,7 +409,7 @@ public class GeckoThread extends Thread {
}
// And go.
GeckoLoader.nativeRun(args, mCrashFileDescriptor, mIPCFileDescriptor);
GeckoLoader.nativeRun(args, mCrashFileDescriptor, mIPCFileDescriptor, mCrashAnnotationFileDescriptor);
// And... we're done.
final boolean restarting = isState(State.RESTARTING);

Просмотреть файл

@ -493,7 +493,7 @@ public final class GeckoLoader {
private static native void putenv(String map);
// These methods are implemented in mozglue/android/APKOpen.cpp
public static native void nativeRun(String[] args, int crashFd, int ipcFd);
public static native void nativeRun(String[] args, int crashFd, int ipcFd, int crashAnnotationFd);
private static native void loadGeckoLibsNative(String apkName);
private static native void loadSQLiteLibsNative(String apkName);
private static native void loadNSSLibsNative(String apkName);

Просмотреть файл

@ -168,12 +168,14 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
@WrapForJNI
private static int start(final String type, final String[] args,
final int crashFd, final int ipcFd) {
return INSTANCE.start(type, args, crashFd, ipcFd, /* retry */ false);
final int crashFd, final int ipcFd,
final int crashAnnotationFd) {
return INSTANCE.start(type, args, crashFd, ipcFd, crashAnnotationFd, /* retry */ false);
}
private int start(final String type, final String[] args, final int crashFd,
final int ipcFd, final boolean retry) {
final int ipcFd, final int crashAnnotationFd,
final boolean retry) {
final ChildConnection connection = getConnection(type);
final IChildProcess child = connection.bind();
if (child == null) {
@ -182,9 +184,11 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
final ParcelFileDescriptor crashPfd;
final ParcelFileDescriptor ipcPfd;
final ParcelFileDescriptor crashAnnotationPfd;
try {
crashPfd = (crashFd >= 0) ? ParcelFileDescriptor.fromFd(crashFd) : null;
ipcPfd = ParcelFileDescriptor.fromFd(ipcFd);
crashAnnotationPfd = (crashAnnotationFd >= 0) ? ParcelFileDescriptor.fromFd(crashAnnotationFd) : null;
} catch (final IOException e) {
Log.e(LOGTAG, "Cannot create fd for " + type, e);
return 0;
@ -192,7 +196,7 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
boolean started = false;
try {
started = child.start(this, args, crashPfd, ipcPfd);
started = child.start(this, args, crashPfd, ipcPfd, crashAnnotationPfd);
} catch (final RemoteException e) {
}
@ -203,7 +207,7 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
}
Log.w(LOGTAG, "Attempting to kill running child " + type);
connection.unbind();
return start(type, args, crashFd, ipcFd, /* retry */ true);
return start(type, args, crashFd, ipcFd, crashAnnotationFd, /* retry */ true);
}
try {

Просмотреть файл

@ -62,7 +62,8 @@ public class GeckoServiceChildProcess extends Service {
public boolean start(final IProcessManager procMan,
final String[] args,
final ParcelFileDescriptor crashReporterPfd,
final ParcelFileDescriptor ipcPfd) {
final ParcelFileDescriptor ipcPfd,
final ParcelFileDescriptor crashAnnotationPfd) {
synchronized (GeckoServiceChildProcess.class) {
if (sProcessManager != null) {
Log.e(LOGTAG, "Child process already started");
@ -74,11 +75,12 @@ public class GeckoServiceChildProcess extends Service {
final int crashReporterFd = crashReporterPfd != null ?
crashReporterPfd.detachFd() : -1;
final int ipcFd = ipcPfd != null ? ipcPfd.detachFd() : -1;
final int crashAnnotationFd = crashAnnotationPfd != null ? crashAnnotationPfd.detachFd() : -1;
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (GeckoThread.initChildProcess(args, crashReporterFd, ipcFd)) {
if (GeckoThread.initChildProcess(args, crashReporterFd, ipcFd, crashAnnotationFd)) {
GeckoThread.launch();
}
}

Просмотреть файл

@ -408,7 +408,7 @@ FreeArgv(char** argv, int argc)
}
extern "C" APKOPEN_EXPORT void MOZ_JNICALL
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int crashFd, int ipcFd)
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int crashFd, int ipcFd, int crashAnnotationFd)
{
int argc = 0;
char** argv = CreateArgvFromObjectArray(jenv, jargs, &argc);
@ -423,7 +423,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jo
gBootstrap->GeckoStart(jenv, argv, argc, sAppData);
ElfLoader::Singleton.ExpectShutdown(true);
} else {
gBootstrap->XRE_SetAndroidChildFds(jenv, crashFd, ipcFd);
gBootstrap->XRE_SetAndroidChildFds(jenv, crashFd, ipcFd, crashAnnotationFd);
gBootstrap->XRE_SetProcessType(argv[argc - 1]);
XREChildData childData;

Просмотреть файл

@ -141,6 +141,24 @@ SetRestartArgs(int argc, char** argv)
return NS_ERROR_NOT_IMPLEMENTED;
}
#if !defined(XP_WIN)
int
GetAnnotationTimeCrashFd()
{
return 7;
}
#endif
void
RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess, PRFileDesc* aFd)
{
}
void
DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess)
{
}
#ifdef XP_WIN32
nsresult
WriteMinidumpForException(EXCEPTION_POINTERS* aExceptionInfo)
@ -298,16 +316,10 @@ GetLastRunCrashID(nsAString& id)
return false;
}
#if defined(XP_WIN) || defined(XP_MACOSX)
void
InitChildProcessTmpDir(nsIFile* aDirOverride)
{
}
#endif // defined(XP_WIN) || defined(XP_MACOSX)
#if defined(XP_WIN)
bool
SetRemoteExceptionHandler(const nsACString& crashPipe)
SetRemoteExceptionHandler(const nsACString& crashPipe,
uintptr_t aCrashTimeAnnotationFile)
{
return false;
}
@ -391,6 +403,11 @@ SetNotificationPipeForChild(int childCrashFd)
{
}
void
SetCrashAnnotationPipeForChild(int childCrashAnnotationFd)
{
}
void
AddLibraryMapping(const char* library_name,
uintptr_t start_address,

Просмотреть файл

@ -25,6 +25,7 @@
#include "nsXULAppAPI.h"
#include "jsfriendapi.h"
#include "ThreadAnnotation.h"
#include "private/pprio.h"
#if defined(XP_WIN32)
#ifdef WIN32_LEAN_AND_MEAN
@ -242,6 +243,7 @@ static bool sIncludeContextHeap = false;
// OOP crash reporting
static CrashGenerationServer* crashServer; // chrome process has this
static std::map<ProcessId, PRFileDesc*> processToCrashFd;
static std::terminate_handler oldTerminateHandler = nullptr;
@ -269,6 +271,10 @@ static int gMagicChildCrashReportFd =
;
# endif
#if defined(MOZ_WIDGET_ANDROID)
static int gChildCrashAnnotationReportFd = -1;
#endif
// |dumpMapLock| must protect all access to |pidToMinidump|.
static Mutex* dumpMapLock;
struct ChildProcessData : public nsUint32HashKey
@ -579,6 +585,8 @@ public:
nullptr);
}
void OpenHandle(HANDLE aHandle) { mHandle = aHandle; }
bool Valid() {
return mHandle != INVALID_HANDLE_VALUE;
}
@ -625,6 +633,8 @@ public:
mFD = sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
}
void OpenHandle(int aFd) { mFD = aFd; }
bool Valid() {
return mFD != -1;
}
@ -1261,45 +1271,18 @@ BuildTempPath(PathStringT& aResult)
}
static void
PrepareChildExceptionTimeAnnotations()
PrepareChildExceptionTimeAnnotations(void* context)
{
MOZ_ASSERT(!XRE_IsParentProcess());
static XP_CHAR tempPath[XP_PATH_MAX] = {0};
// Get the temp path
size_t charsAvailable = XP_PATH_MAX;
XP_CHAR* p = tempPath;
#if (defined(XP_MACOSX) || defined(XP_WIN))
if (!childProcessTmpDir || childProcessTmpDir->empty()) {
return;
}
p = Concat(p, childProcessTmpDir->c_str(), &charsAvailable);
// Ensure that this path ends with a path separator
if (p > tempPath && *(p - 1) != XP_PATH_SEPARATOR_CHAR) {
p = Concat(p, XP_PATH_SEPARATOR, &charsAvailable);
}
FileHandle f;
#ifdef XP_WIN
f = static_cast<HANDLE>(context);
#else
size_t tempPathLen = BuildTempPath(tempPath);
if (!tempPathLen) {
return;
}
p += tempPathLen;
charsAvailable -= tempPathLen;
f = GetAnnotationTimeCrashFd();
#endif
// Generate and append the file name
p = Concat(p, childCrashAnnotationBaseName, &charsAvailable);
XP_CHAR pidBuffer[32] = XP_TEXT("");
#if defined(XP_WIN32)
_ui64tow(GetCurrentProcessId(), pidBuffer, 10);
#else
XP_STOA(getpid(), pidBuffer, 10);
#endif
p = Concat(p, pidBuffer, &charsAvailable);
// Now open the file...
PlatformWriter apiData;
OpenAPIData(apiData, tempPath);
apiData.OpenHandle(f);
// ...and write out any annotations. These must be escaped if necessary
// (but don't call EscapeAnnotation here, because it touches the heap).
@ -1395,7 +1378,7 @@ ChildFPEFilter(void* context, EXCEPTION_POINTERS* exinfo,
{
bool result = FPEFilter(context, exinfo, assertion);
if (result) {
PrepareChildExceptionTimeAnnotations();
PrepareChildExceptionTimeAnnotations(context);
}
return result;
}
@ -1461,7 +1444,7 @@ ChildFilter(void* context)
{
bool result = Filter(context);
if (result) {
PrepareChildExceptionTimeAnnotations();
PrepareChildExceptionTimeAnnotations(context);
}
return result;
}
@ -3056,50 +3039,6 @@ AppendExtraData(nsIFile* extraFile, const AnnotationTable& data)
return WriteExtraData(extraFile, data, Blacklist());
}
static bool
GetExtraFileForChildPid(uint32_t aPid, nsIFile** aExtraFile)
{
MOZ_ASSERT(XRE_IsParentProcess());
nsCOMPtr<nsIFile> extraFile;
nsresult rv;
#if defined(XP_WIN) || defined(XP_MACOSX)
if (!childProcessTmpDir) {
return false;
}
CreateFileFromPath(*childProcessTmpDir, getter_AddRefs(extraFile));
if (!extraFile) {
return false;
}
#elif defined(XP_UNIX)
rv = NS_NewLocalFile(NS_LITERAL_STRING("/tmp"), false,
getter_AddRefs(extraFile));
if (NS_FAILED(rv)) {
return false;
}
#else
#error "Implement this for your platform"
#endif
nsAutoString leafName;
#if defined(XP_WIN)
leafName.AppendPrintf("%S%u%S", childCrashAnnotationBaseName, aPid,
extraFileExtension);
#else
leafName.AppendPrintf("%s%u%s", childCrashAnnotationBaseName, aPid,
extraFileExtension);
#endif
rv = extraFile->Append(leafName);
if (NS_FAILED(rv)) {
return false;
}
extraFile.forget(aExtraFile);
return true;
}
static bool
IsDataEscaped(char* aData)
{
@ -3174,19 +3113,27 @@ WriteExtraForMinidump(nsIFile* minidump,
return false;
}
nsCOMPtr<nsIFile> exceptionTimeExtra;
FILE* fd;
if (pid && GetExtraFileForChildPid(pid, getter_AddRefs(exceptionTimeExtra)) &&
NS_SUCCEEDED(exceptionTimeExtra->OpenANSIFileDesc("r", &fd))) {
AnnotationTable exceptionTimeAnnotations;
ReadAndValidateExceptionTimeAnnotations(fd, exceptionTimeAnnotations);
fclose(fd);
if (!AppendExtraData(extra, exceptionTimeAnnotations)) {
if (pid && processToCrashFd.count(pid)) {
PRFileDesc* prFd = processToCrashFd[pid];
processToCrashFd.erase(pid);
FILE* fd;
#if defined(XP_WIN)
int nativeFd = _open_osfhandle(PR_FileDesc2NativeHandle(prFd), 0);
if (nativeFd == -1) {
return false;
}
}
if (exceptionTimeExtra) {
exceptionTimeExtra->Remove(false);
fd = fdopen(nativeFd, "r");
#else
fd = fdopen(PR_FileDesc2NativeHandle(prFd), "r");
#endif
if (fd) {
AnnotationTable exceptionTimeAnnotations;
ReadAndValidateExceptionTimeAnnotations(fd, exceptionTimeAnnotations);
PR_Close(prFd);
if (!AppendExtraData(extra, exceptionTimeAnnotations)) {
return false;
}
}
}
extra.forget(extraFile);
@ -3538,30 +3485,39 @@ UnregisterInjectorCallback(DWORD processID)
#endif // MOZ_CRASHREPORTER_INJECTOR
#if defined(XP_WIN) || defined(XP_MACOSX)
void
InitChildProcessTmpDir(nsIFile* aDirOverride)
#if !defined(XP_WIN)
int
GetAnnotationTimeCrashFd()
{
MOZ_ASSERT(!XRE_IsParentProcess());
if (aDirOverride) {
childProcessTmpDir = CreatePathFromFile(aDirOverride);
return;
}
#if defined(MOZ_WIDGET_ANDROID)
return gChildCrashAnnotationReportFd;
#else
return 7;
#endif // defined(MOZ_WIDGET_ANDROID)
}
#endif
// When retrieved by the child process, this will always resolve to the
// correct directory regardless of sandbox level.
nsCOMPtr<nsIFile> tmpDir;
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir));
if (NS_SUCCEEDED(rv)) {
childProcessTmpDir = CreatePathFromFile(tmpDir);
void
RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess, PRFileDesc* aFd)
{
processToCrashFd[aProcess] = aFd;
}
void
DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess)
{
auto it = processToCrashFd.find(aProcess);
if (it != processToCrashFd.end()) {
PR_Close(it->second);
processToCrashFd.erase(it);
}
}
#endif // defined(XP_WIN) || defined(XP_MACOSX)
#if defined(XP_WIN)
// Child-side API
bool
SetRemoteExceptionHandler(const nsACString& crashPipe)
SetRemoteExceptionHandler(const nsACString& crashPipe,
uintptr_t aCrashTimeAnnotationFile)
{
// crash reporting is disabled
if (crashPipe.Equals(kNullNotifyPipe))
@ -3569,15 +3525,15 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
MOZ_ASSERT(!gExceptionHandler, "crash client already init'd");
gExceptionHandler = new google_breakpad::
ExceptionHandler(L"",
ChildFPEFilter,
nullptr, // no minidump callback
nullptr, // no callback context
google_breakpad::ExceptionHandler::HANDLER_ALL,
GetMinidumpType(),
NS_ConvertASCIItoUTF16(crashPipe).get(),
nullptr);
gExceptionHandler = new google_breakpad::ExceptionHandler(
L"",
ChildFPEFilter,
nullptr, // no minidump callback
reinterpret_cast<void*>(aCrashTimeAnnotationFile),
google_breakpad::ExceptionHandler::HANDLER_ALL,
GetMinidumpType(),
NS_ConvertASCIItoUTF16(crashPipe).get(),
nullptr);
gExceptionHandler->set_handle_debug_exceptions(true);
RunAndCleanUpDelayedNotes();
@ -4081,6 +4037,11 @@ void SetNotificationPipeForChild(int childCrashFd)
gMagicChildCrashReportFd = childCrashFd;
}
void SetCrashAnnotationPipeForChild(int childCrashAnnotationFd)
{
gChildCrashAnnotationReportFd = childCrashAnnotationFd;
}
void AddLibraryMapping(const char* library_name,
uintptr_t start_address,
size_t mapping_length,

Просмотреть файл

@ -19,6 +19,7 @@
#include <stdint.h>
#include "nsError.h"
#include "nsString.h"
#include "prio.h"
#if defined(XP_WIN32)
#ifdef WIN32_LEAN_AND_MEAN
@ -176,15 +177,30 @@ bool TakeMinidumpForChild(uint32_t childPid,
#if defined(XP_WIN)
typedef HANDLE ProcessHandle;
typedef DWORD ProcessId;
typedef DWORD ThreadId;
typedef HANDLE FileHandle;
#elif defined(XP_MACOSX)
typedef task_t ProcessHandle;
typedef pid_t ProcessId;
typedef mach_port_t ThreadId;
typedef int FileHandle;
#else
typedef int ProcessHandle;
typedef pid_t ProcessId;
typedef int ThreadId;
typedef int FileHandle;
#endif
#if !defined(XP_WIN)
int
GetAnnotationTimeCrashFd();
#endif
void
RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess, PRFileDesc* aFd);
void
DeregisterChildCrashAnnotationFileDescriptor(ProcessId aProcess);
// Return the current thread's ID.
//
// XXX: this is a somewhat out-of-place interface to expose through
@ -264,8 +280,13 @@ void UnregisterInjectorCallback(DWORD processID);
#endif
// Child-side API
#if defined(XP_WIN32)
bool
SetRemoteExceptionHandler(const nsACString& crashPipe,
uintptr_t aCrashTimeAnnotationFile);
#else
bool SetRemoteExceptionHandler(const nsACString& crashPipe);
void InitChildProcessTmpDir(nsIFile* aDirOverride = nullptr);
#endif
# else
// Parent-side API for children
@ -291,6 +312,7 @@ bool UnsetRemoteExceptionHandler();
// Android creates child process as services so we must explicitly set
// the handle for the pipe since it can't get remapped to a default value.
void SetNotificationPipeForChild(int childCrashFd);
void SetCrashAnnotationPipeForChild(int childCrashAnnotationFd);
// Android builds use a custom library loader, so /proc/<pid>/maps
// will just show anonymous mappings for all the non-system

Просмотреть файл

@ -78,8 +78,8 @@ public:
::GeckoStart(aEnv, argv, argc, aAppData);
}
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd) override {
::XRE_SetAndroidChildFds(aEnv, aCrashFd, aIPCFd);
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd, int aCrashAnnotationFd) override {
::XRE_SetAndroidChildFds(aEnv, aCrashFd, aIPCFd, aCrashAnnotationFd);
}
#endif

Просмотреть файл

@ -113,7 +113,7 @@ public:
#ifdef MOZ_WIDGET_ANDROID
virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc, const StaticXREAppData& aAppData) = 0;
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd) = 0;
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aCrashFd, int aIPCFd, int aCrashAnnotationFd) = 0;
#endif
#ifdef LIBFUZZER

Просмотреть файл

@ -243,10 +243,11 @@ GeckoProcessType sChildProcessType = GeckoProcessType_Default;
#if defined(MOZ_WIDGET_ANDROID)
void
XRE_SetAndroidChildFds (JNIEnv* env, int crashFd, int ipcFd)
XRE_SetAndroidChildFds (JNIEnv* env, int crashFd, int ipcFd, int crashAnnotationFd)
{
mozilla::jni::SetGeckoThreadEnv(env);
CrashReporter::SetNotificationPipeForChild(crashFd);
CrashReporter::SetCrashAnnotationPipeForChild(crashAnnotationFd);
IPC::Channel::SetClientChannelFd(ipcFd);
}
#endif // defined(MOZ_WIDGET_ANDROID)
@ -282,9 +283,17 @@ XRE_TakeMinidumpForChild(uint32_t aChildPid, nsIFile** aDump,
}
bool
XRE_SetRemoteExceptionHandler(const char* aPipe/*= 0*/)
#if defined(XP_WIN)
XRE_SetRemoteExceptionHandler(const char* aPipe /*= 0*/,
uintptr_t aCrashTimeAnnotationFile)
#else
XRE_SetRemoteExceptionHandler(const char* aPipe /*= 0*/)
#endif
{
#if defined(XP_WIN) || defined(XP_MACOSX)
#if defined(XP_WIN)
return CrashReporter::SetRemoteExceptionHandler(nsDependentCString(aPipe),
aCrashTimeAnnotationFile);
#elif defined(XP_MACOSX)
return CrashReporter::SetRemoteExceptionHandler(nsDependentCString(aPipe));
#else
return CrashReporter::SetRemoteExceptionHandler();
@ -479,13 +488,20 @@ XRE_InitChildProcess(int aArgc,
SetupErrorHandling(aArgv[0]);
if (!CrashReporter::IsDummy()) {
#if defined(XP_WIN)
if (aArgc < 1) {
return NS_ERROR_FAILURE;
}
const char* const crashTimeAnnotationArg = aArgv[--aArgc];
uintptr_t crashTimeAnnotationFile =
static_cast<uintptr_t>(std::stoul(std::string(crashTimeAnnotationArg)));
#endif
if (aArgc < 1)
return NS_ERROR_FAILURE;
const char* const crashReporterArg = aArgv[--aArgc];
#if defined(XP_WIN) || defined(XP_MACOSX)
#if defined(XP_MACOSX)
// on windows and mac, |crashReporterArg| is the named pipe on which the
// server is listening for requests, or "-" if crash reporting is
// disabled.
@ -494,6 +510,13 @@ XRE_InitChildProcess(int aArgc,
// Bug 684322 will add better visibility into this condition
NS_WARNING("Could not setup crash reporting\n");
}
#elif defined(XP_WIN)
if (0 != strcmp("-", crashReporterArg) &&
!XRE_SetRemoteExceptionHandler(crashReporterArg,
crashTimeAnnotationFile)) {
// Bug 684322 will add better visibility into this condition
NS_WARNING("Could not setup crash reporting\n");
}
#else
// on POSIX, |crashReporterArg| is "true" if crash reporting is
// enabled, false otherwise
@ -672,10 +695,6 @@ XRE_InitChildProcess(int aArgc,
return NS_ERROR_FAILURE;
}
#if defined(XP_WIN) || defined(XP_MACOSX)
CrashReporter::InitChildProcessTmpDir(crashReportTmpDir);
#endif
#if defined(XP_WIN)
// Set child processes up such that they will get killed after the
// chrome process is killed in cases where the user shuts the system

Просмотреть файл

@ -2401,9 +2401,9 @@ constexpr char GeckoProcessManager::GetEditableParent_t::signature[];
constexpr char GeckoProcessManager::Start_t::name[];
constexpr char GeckoProcessManager::Start_t::signature[];
auto GeckoProcessManager::Start(mozilla::jni::String::Param a0, mozilla::jni::ObjectArray::Param a1, int32_t a2, int32_t a3) -> int32_t
auto GeckoProcessManager::Start(mozilla::jni::String::Param a0, mozilla::jni::ObjectArray::Param a1, int32_t a2, int32_t a3, int32_t a4) -> int32_t
{
return mozilla::jni::Method<Start_t>::Call(GeckoProcessManager::Context(), nullptr, a0, a1, a2, a3);
return mozilla::jni::Method<Start_t>::Call(GeckoProcessManager::Context(), nullptr, a0, a1, a2, a3, a4);
}
const char GeckoServiceChildProcess::name[] =

Просмотреть файл

@ -6921,10 +6921,11 @@ public:
mozilla::jni::String::Param,
mozilla::jni::ObjectArray::Param,
int32_t,
int32_t,
int32_t> Args;
static constexpr char name[] = "start";
static constexpr char signature[] =
"(Ljava/lang/String;[Ljava/lang/String;II)I";
"(Ljava/lang/String;[Ljava/lang/String;III)I";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
@ -6934,7 +6935,7 @@ public:
mozilla::jni::DispatchTarget::CURRENT;
};
static auto Start(mozilla::jni::String::Param, mozilla::jni::ObjectArray::Param, int32_t, int32_t) -> int32_t;
static auto Start(mozilla::jni::String::Param, mozilla::jni::ObjectArray::Param, int32_t, int32_t, int32_t) -> int32_t;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;

Просмотреть файл

@ -398,7 +398,7 @@ XRE_API(const char*,
#if defined(MOZ_WIDGET_ANDROID)
XRE_API(void,
XRE_SetAndroidChildFds, (JNIEnv* env, int crashFd, int ipcFd))
XRE_SetAndroidChildFds, (JNIEnv* env, int crashFd, int ipcFd, int crashAnnotationFd))
#endif // defined(MOZ_WIDGET_ANDROID)
XRE_API(void,
@ -410,8 +410,16 @@ XRE_API(bool,
uint32_t* aSequence))
// Used in child processes.
#if defined(XP_WIN)
// Uses uintptr_t, even though it's really a HANDLE, because including
// <windows.h> here caused compilation issues.
XRE_API(bool,
XRE_SetRemoteExceptionHandler,
(const char* aPipe, uintptr_t aCrashTimeAnnotationFile))
#else
XRE_API(bool,
XRE_SetRemoteExceptionHandler, (const char* aPipe))
#endif
namespace mozilla {
namespace gmp {