Bug 1350435 - Compute snapshot ID in the parent process. r=fitzgen,smaug

The parent and content processes can have different temp directories
when sandboxing is enabled, so the process that creates the file for a
heap snapshot must also determine the snapshot ID.

MozReview-Commit-ID: 2UuncT54NXc

--HG--
extra : rebase_source : 350e49bf7c570abfdde457a89ee8922f8cdb8b7d
This commit is contained in:
Andrew McCreight 2017-03-24 10:34:44 -07:00
Родитель 5d98501bcf
Коммит 855f08b5d6
8 изменённых файлов: 80 добавлений и 26 удалений

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

@ -155,8 +155,7 @@ exports.Memory = Class({
boundaries = { debugger: this.dbg };
}
}
const path = ThreadSafeChromeUtils.saveHeapSnapshot(boundaries);
return HeapSnapshotFileUtils.getSnapshotIdFromPath(path);
return ThreadSafeChromeUtils.saveHeapSnapshotGetId(boundaries);
}, "saveHeapSnapshot"),
/**

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

@ -1444,13 +1444,19 @@ msSinceProcessCreation(const TimeStamp& now)
/* static */ already_AddRefed<nsIFile>
HeapSnapshot::CreateUniqueCoreDumpFile(ErrorResult& rv,
const TimeStamp& now,
nsAString& outFilePath)
nsAString& outFilePath,
nsAString& outSnapshotId)
{
nsCOMPtr<nsIFile> file;
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(file));
if (NS_WARN_IF(rv.Failed()))
return nullptr;
nsAutoString tempPath;
rv = file->GetPath(tempPath);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
auto ms = msSinceProcessCreation(now);
rv = file->AppendNative(nsPrintfCString("%lu.fxsnapshot", ms));
if (NS_WARN_IF(rv.Failed()))
@ -1462,7 +1468,12 @@ HeapSnapshot::CreateUniqueCoreDumpFile(ErrorResult& rv,
rv = file->GetPath(outFilePath);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
return nullptr;
// The snapshot ID must be computed in the process that created the
// temp file, because TmpD may not be the same in all processes.
outSnapshotId.Assign(Substring(outFilePath, tempPath.Length() + 1,
outFilePath.Length() - tempPath.Length() - sizeof(".fxsnapshot")));
return file.forget();
}
@ -1489,14 +1500,18 @@ using UniqueHeapSnapshotTempFileHelperChild = UniquePtr<PHeapSnapshotTempFileHel
// the filesystem. Use IPDL to request a file descriptor from the parent
// process.
static already_AddRefed<nsIOutputStream>
getCoreDumpOutputStream(ErrorResult& rv, TimeStamp& start, nsAString& outFilePath)
getCoreDumpOutputStream(ErrorResult& rv,
TimeStamp& start,
nsAString& outFilePath,
nsAString& outSnapshotId)
{
if (XRE_IsParentProcess()) {
// Create the file and open the output stream directly.
nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
start,
outFilePath);
outFilePath,
outSnapshotId);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
@ -1535,6 +1550,7 @@ getCoreDumpOutputStream(ErrorResult& rv, TimeStamp& start, nsAString& outFilePat
auto opened = response.get_OpenedFile();
outFilePath = opened.path();
outSnapshotId = opened.snapshotId();
nsCOMPtr<nsIOutputStream> outputStream =
FileDescriptorOutputStream::Create(opened.descriptor());
if (NS_WARN_IF(!outputStream)) {
@ -1553,10 +1569,11 @@ using namespace JS;
using namespace devtools;
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
ErrorResult& rv)
ThreadSafeChromeUtils::SaveHeapSnapshotShared(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
nsAString& outSnapshotId,
ErrorResult& rv)
{
auto start = TimeStamp::Now();
@ -1565,7 +1582,9 @@ ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
uint32_t nodeCount = 0;
uint32_t edgeCount = 0;
nsCOMPtr<nsIOutputStream> outputStream = getCoreDumpOutputStream(rv, start, outFilePath);
nsCOMPtr<nsIOutputStream> outputStream = getCoreDumpOutputStream(rv, start,
outFilePath,
outSnapshotId);
if (NS_WARN_IF(rv.Failed()))
return;
@ -1618,6 +1637,26 @@ ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
edgeCount);
}
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
ErrorResult& rv)
{
nsAutoString snapshotId;
SaveHeapSnapshotShared(global, boundaries, outFilePath, snapshotId, rv);
}
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshotGetId(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outSnapshotId,
ErrorResult& rv)
{
nsAutoString filePath;
SaveHeapSnapshotShared(global, boundaries, filePath, outSnapshotId, rv);
}
/* static */ already_AddRefed<HeapSnapshot>
ThreadSafeChromeUtils::ReadHeapSnapshot(GlobalObject& global,
const nsAString& filePath,

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

@ -126,7 +126,8 @@ public:
// snapshots are serialized into.
static already_AddRefed<nsIFile> CreateUniqueCoreDumpFile(ErrorResult& rv,
const TimeStamp& now,
nsAString& outFilePath);
nsAString& outFilePath,
nsAString& outSnapshotId);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HeapSnapshot)

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

@ -81,15 +81,3 @@ exports.haveHeapSnapshotTempFile = function (snapshotId) {
return OS.File.stat(path).then(() => true,
() => false);
};
/**
* Given a heap snapshot's file path, extricate the snapshot id.
*
* @param {String} path
*
* @returns String
*/
exports.getSnapshotIdFromPath = function (path) {
return path.slice(OS.Constants.Path.tmpDir.length + 1,
path.length - ".fxsnapshot".length);
};

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

@ -31,9 +31,11 @@ HeapSnapshotTempFileHelperParent::RecvOpenHeapSnapshotTempFile(
auto start = TimeStamp::Now();
ErrorResult rv;
nsAutoString filePath;
nsAutoString snapshotId;
nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
start,
filePath);
filePath,
snapshotId);
if (NS_WARN_IF(rv.Failed())) {
if (!openFileFailure(rv, outResponse)) {
return IPC_FAIL_NO_REASON(this);
@ -53,7 +55,7 @@ HeapSnapshotTempFileHelperParent::RecvOpenHeapSnapshotTempFile(
FileDescriptor::PlatformHandleType handle =
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfd));
FileDescriptor fd(handle);
*outResponse = OpenedFile(filePath, fd);
*outResponse = OpenedFile(filePath, snapshotId, fd);
return IPC_OK();
}

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

@ -12,6 +12,7 @@ namespace devtools {
struct OpenedFile
{
nsString path;
nsString snapshotId;
FileDescriptor descriptor;
};

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

@ -26,6 +26,14 @@ class Promise;
class ThreadSafeChromeUtils
{
private:
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshotShared(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& filePath,
nsAString& snapshotId,
ErrorResult& rv);
public:
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshot(GlobalObject& global,
@ -33,6 +41,12 @@ public:
nsAString& filePath,
ErrorResult& rv);
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshotGetId(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& snapshotId,
ErrorResult& rv);
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static already_AddRefed<devtools::HeapSnapshot> ReadHeapSnapshot(GlobalObject& global,
const nsAString& filePath,

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

@ -24,6 +24,16 @@ interface ThreadSafeChromeUtils {
[Throws]
static DOMString saveHeapSnapshot(optional HeapSnapshotBoundaries boundaries);
/**
* This is the same as saveHeapSnapshot, but with a different return value.
*
* @returns The snapshot ID of the file. This is the file name
* without the temp directory or the trailing
* `.fxsnapshot`.
*/
[Throws]
static DOMString saveHeapSnapshotGetId(optional HeapSnapshotBoundaries boundaries);
/**
* Deserialize a core dump into a HeapSnapshot.
*