зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1587722) for causing xpcshell failures on test_crashreporter_crash.js CLOSED TREE
Backed out changeset 6aad53d9e447 (bug 1587722) Backed out changeset 7d664635c1dc (bug 1587722) Backed out changeset c9dbcfa6a938 (bug 1587722) --HG-- rename : toolkit/crashreporter/test/unit/test_oom_annotation.js => toolkit/crashreporter/test/unit/test_oom_annotation_windows.js
This commit is contained in:
Родитель
7d9dd50759
Коммит
f26446fbad
|
@ -104,13 +104,9 @@ AsyncShutdownTimeout:
|
|||
|
||||
AvailablePageFile:
|
||||
description: >
|
||||
Available commit-space in bytes.
|
||||
- Under Windows, computed from the PERFORMANCE_INFORMATION structure by substracting
|
||||
the CommitTotal field from the CommitLimit field.
|
||||
- Under Linux, computed from /proc/meminfo's CommitLimit - Committed_AS. Note that
|
||||
the kernel is not guaranteed to enforce that CommittedLimit >= Committed_AS. If
|
||||
Committed_AS > CommittedLimit, this value is set to 0.
|
||||
- Not available on other platforms.
|
||||
Windows-only, available commit-space in bytes. This annotation is computed
|
||||
from the PERFORMANCE_INFORMATION structure by substracting the CommitTotal
|
||||
field from the CommitLimit field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
|
@ -120,28 +116,22 @@ AvailablePhysicalMemory:
|
|||
- Under Windows, populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullAvailPhys field.
|
||||
- Under macOS, populated with vm_statistics64_data_t::free_count.
|
||||
- Under Linux, populated with /proc/meminfo's MemFree.
|
||||
- Not available on other platforms.
|
||||
- Not available under other platforms.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
AvailableSwapMemory:
|
||||
description: >
|
||||
Amount of free swap space in bytes.
|
||||
- Under macOS, populated with the contents of
|
||||
sysctl "vm.swapusage" :: xsu_avail.
|
||||
- Under Linux, populated with /proc/meminfo's SwapFree.
|
||||
- Not available on other platforms.
|
||||
macOS-only, amount of free swap space. Populated with the coontents of
|
||||
sysctl "vm.swapusage" :: xsu_avail.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
AvailableVirtualMemory:
|
||||
description: >
|
||||
Amount of free virtual memory in bytes
|
||||
- Under Windows, populated with the contents of the MEMORYSTATUSEX's structure ullAvailVirtual field.
|
||||
- Under Linux, populated with /proc/meminfo's MemAvailable.
|
||||
- Not available on other platforms.
|
||||
- For macOS, see AvailableSwapMemory, AvailablePhysicalMemory and PurgeablePhysicalMemory.
|
||||
Windows-only, amount of free virtual memory in bytes. Populated with the contents
|
||||
of the MEMORYSTATUSEX's structure ullAvailVirtual field.
|
||||
For macOS, see AvailableSwapMemory, AvailablePhysicalMemory and PurgeablePhysicalMemory.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
|
@ -853,11 +843,9 @@ ThreadIdNameMapping:
|
|||
|
||||
TotalPageFile:
|
||||
description: >
|
||||
Maximum amount of memory that can be committed without extending the swap/page file.
|
||||
Maximum amount of memory that can be committed.
|
||||
- Under Windows, populated with the contents of the PERFORMANCE_INFORMATION's
|
||||
structure CommitLimit field.
|
||||
- Under Linux, populated with /proc/meminfo MemTotal + SwapTotal. The swap file
|
||||
typically cannot be extended, so that's a hard limit.
|
||||
- Not available on other systems.
|
||||
type: string
|
||||
ping: true
|
||||
|
@ -868,17 +856,14 @@ TotalPhysicalMemory:
|
|||
- Under Windows, populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalPhys field.
|
||||
- Under macOS, populated with sysctl "hw.memsize".
|
||||
- Under Linux, populated with /proc/meminfo's "MemTotal".
|
||||
- Not available on other systems.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
TotalVirtualMemory:
|
||||
description: >
|
||||
Size of the virtual address space.
|
||||
- Under Windows, populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalVirtual field.
|
||||
- Not available on other platforms.
|
||||
Windows-only. Size of the virtual address space. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalVirtual field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
# include "common/linux/eintr_wrapper.h"
|
||||
# include <fcntl.h>
|
||||
# include <sys/types.h>
|
||||
# include "sys/sysinfo.h"
|
||||
# include <sys/wait.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
|
@ -771,63 +770,50 @@ static void OpenAPIData(PlatformWriter& aWriter, const XP_CHAR* dump_path,
|
|||
aWriter.Open(extraDataPath);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
|
||||
static void WriteMemoryAnnotation(AnnotationTable& aTable,
|
||||
static void WriteMemoryAnnotation(AnnotationWriter& aWriter,
|
||||
Annotation aAnnotation, uint64_t aValue) {
|
||||
// This function is used to write values of 64 bits, which can safely be
|
||||
// assumed to fit within 20 decimal digits, so we need neither allocation nor
|
||||
// overflow checking.
|
||||
char buffer[128];
|
||||
# ifdef XP_LINUX
|
||||
// Under Linux, we cannot call into libc from the exception handler,
|
||||
// so we need to call `my_inttostring`.
|
||||
intmax_t value = intmax_t(aValue);
|
||||
if (uint64_t(value) != aValue) {
|
||||
// Our uint64_t doesn't cast properly to intmax_t. In this (unlikely) case,
|
||||
// report the maximal value that can be represented with intmax_t.
|
||||
value = intmax_t(-1);
|
||||
}
|
||||
my_inttostring(value, buffer, sizeof(buffer));
|
||||
aTable[aAnnotation] = nsDependentCString(buffer);
|
||||
# else
|
||||
if (SprintfLiteral(buffer, "%llu", aValue) > 0) {
|
||||
aTable[aAnnotation] = nsDependentCString(buffer);
|
||||
aWriter.Write(aAnnotation, buffer);
|
||||
}
|
||||
# endif // XP_LINUX || else
|
||||
}
|
||||
|
||||
#endif // XP_WIN || XP_MACOSX || XP_LINUX
|
||||
#endif // XP_WIN || XP_MACOSX
|
||||
|
||||
#ifdef XP_WIN
|
||||
static void AnnotateMemoryStatus(AnnotationTable& aTable) {
|
||||
static void WriteMemoryStatus(AnnotationWriter& aWriter) {
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
if (GlobalMemoryStatusEx(&statex)) {
|
||||
WriteMemoryAnnotation(aTable, Annotation::SystemMemoryUsePercentage,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::SystemMemoryUsePercentage,
|
||||
statex.dwMemoryLoad);
|
||||
WriteMemoryAnnotation(aTable, Annotation::TotalVirtualMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::TotalVirtualMemory,
|
||||
statex.ullTotalVirtual);
|
||||
WriteMemoryAnnotation(aTable, Annotation::AvailableVirtualMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::AvailableVirtualMemory,
|
||||
statex.ullAvailVirtual);
|
||||
WriteMemoryAnnotation(aTable, Annotation::TotalPhysicalMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::TotalPhysicalMemory,
|
||||
statex.ullTotalPhys);
|
||||
WriteMemoryAnnotation(aTable, Annotation::AvailablePhysicalMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::AvailablePhysicalMemory,
|
||||
statex.ullAvailPhys);
|
||||
}
|
||||
|
||||
PERFORMANCE_INFORMATION info;
|
||||
if (K32GetPerformanceInfo(&info, sizeof(info))) {
|
||||
WriteMemoryAnnotation(aTable, Annotation::TotalPageFile,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::TotalPageFile,
|
||||
info.CommitLimit * info.PageSize);
|
||||
WriteMemoryAnnotation(
|
||||
aTable, Annotation::AvailablePageFile,
|
||||
aWriter, Annotation::AvailablePageFile,
|
||||
(info.CommitLimit - info.CommitTotal) * info.PageSize);
|
||||
}
|
||||
}
|
||||
#elif XP_MACOSX
|
||||
// Extract the total physical memory of the system.
|
||||
static void WritePhysicalMemoryStatus(AnnotationTable& aTable) {
|
||||
static void WritePhysicalMemoryStatus(AnnotationWriter& aWriter) {
|
||||
uint64_t physicalMemoryByteSize = 0;
|
||||
const size_t NAME_LEN = 2;
|
||||
int name[NAME_LEN] = {/* Hardware */ CTL_HW,
|
||||
|
@ -836,27 +822,27 @@ static void WritePhysicalMemoryStatus(AnnotationTable& aTable) {
|
|||
if (sysctl(name, NAME_LEN, &physicalMemoryByteSize, &infoByteSize,
|
||||
/* We do not replace data */ nullptr,
|
||||
/* We do not replace data */ 0) != -1) {
|
||||
WriteMemoryAnnotation(aTable, Annotation::TotalPhysicalMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::TotalPhysicalMemory,
|
||||
physicalMemoryByteSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract available and purgeable physical memory.
|
||||
static void WriteAvailableMemoryStatus(AnnotationTable& aTable) {
|
||||
static void WriteAvailableMemoryStatus(AnnotationWriter& aWriter) {
|
||||
auto host = mach_host_self();
|
||||
vm_statistics64_data_t stats;
|
||||
unsigned int count = HOST_VM_INFO64_COUNT;
|
||||
if (host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&stats, &count) ==
|
||||
KERN_SUCCESS) {
|
||||
WriteMemoryAnnotation(aTable, Annotation::AvailablePhysicalMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::AvailablePhysicalMemory,
|
||||
stats.free_count * vm_page_size);
|
||||
WriteMemoryAnnotation(aTable, Annotation::PurgeablePhysicalMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::PurgeablePhysicalMemory,
|
||||
stats.purgeable_count * vm_page_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the status of the swap.
|
||||
static void WriteSwapFileStatus(AnnotationTable& aTable) {
|
||||
static void WriteSwapFileStatus(AnnotationWriter& aWriter) {
|
||||
const size_t NAME_LEN = 2;
|
||||
int name[] = {/* Hardware */ CTL_VM,
|
||||
/* 64-bit physical memory size */ VM_SWAPUSAGE};
|
||||
|
@ -865,298 +851,22 @@ static void WriteSwapFileStatus(AnnotationTable& aTable) {
|
|||
if (sysctl(name, NAME_LEN, &swapUsage, &infoByteSize,
|
||||
/* We do not replace data */ nullptr,
|
||||
/* We do not replace data */ 0) != -1) {
|
||||
WriteMemoryAnnotation(aTable, Annotation::AvailableSwapMemory,
|
||||
WriteMemoryAnnotation(aWriter, Annotation::AvailableSwapMemory,
|
||||
swapUsage.xsu_avail);
|
||||
}
|
||||
}
|
||||
static void AnnotateMemoryStatus(AnnotationTable& aTable) {
|
||||
WritePhysicalMemoryStatus(aTable);
|
||||
WriteAvailableMemoryStatus(aTable);
|
||||
WriteSwapFileStatus(aTable);
|
||||
static void WriteMemoryStatus(AnnotationWriter& aWriter) {
|
||||
WritePhysicalMemoryStatus(aWriter);
|
||||
WriteAvailableMemoryStatus(aWriter);
|
||||
WriteSwapFileStatus(aWriter);
|
||||
}
|
||||
|
||||
#elif XP_LINUX
|
||||
|
||||
static void AnnotateMemoryStatus(AnnotationTable& aTable) {
|
||||
// We can't simply call `sysinfo` as this requires libc.
|
||||
// So we need to parse /proc/meminfo.
|
||||
|
||||
// We read the entire file to memory prior to parsing
|
||||
// as it makes the parser code a little bit simpler.
|
||||
// As /proc/meminfo is synchronized via `proc_create_single`,
|
||||
// there's no risk of race condition regardless of how we
|
||||
// read it.
|
||||
|
||||
// The buffer in which we're going to load the entire file.
|
||||
// A typical size for /proc/meminfo is 1kb, so 10kB should
|
||||
// be large enough until further notice.
|
||||
const size_t BUFFER_SIZE_BYTES = 10000;
|
||||
char buffer[BUFFER_SIZE_BYTES];
|
||||
ssize_t bufferLen = 0;
|
||||
|
||||
{
|
||||
// Read and load into memory.
|
||||
int fd = sys_open("/proc/meminfo", O_RDONLY, /* chmod */ 0);
|
||||
if (fd == -1) {
|
||||
// No /proc/meminfo? Well, fail silently.
|
||||
return;
|
||||
}
|
||||
auto Guard = MakeScopeExit([fd]() { mozilla::Unused << sys_close(fd); });
|
||||
|
||||
if ((bufferLen = sys_read(fd, buffer, BUFFER_SIZE_BYTES)) <= 0) {
|
||||
// Cannot read for some reason. Let's give up.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Each line of /proc/meminfo looks like
|
||||
// SomeLabel: number unit
|
||||
// The last line is empty.
|
||||
// Let's write a parser.
|
||||
// Note that we don't care about writing a normative parser, so
|
||||
// we happily skip whitespaces without checking that it's necessary.
|
||||
|
||||
// A stack-allocated structure containing a 0-terminated string.
|
||||
// We could avoid the memory copies and make it a slice at the cost
|
||||
// of a slightly more complicated parser. Since we're not in a
|
||||
// performance-critical section, we didn't.
|
||||
struct DataBuffer {
|
||||
DataBuffer() : data{0}, pos(0) {}
|
||||
// Clear the buffer.
|
||||
void reset() {
|
||||
pos = 0;
|
||||
data[0] = 0;
|
||||
}
|
||||
// Append a character.
|
||||
//
|
||||
// In case of error (if c is '\0' or the buffer is full), does nothing.
|
||||
void append(char c) {
|
||||
if (c == 0 || pos >= sizeof(data) - 1) {
|
||||
return;
|
||||
}
|
||||
data[pos++] = c;
|
||||
data[pos] = 0;
|
||||
}
|
||||
// Compare the buffer against a nul-terminated string.
|
||||
bool operator==(const char* s) const {
|
||||
for (size_t i = 0; i < pos; ++i) {
|
||||
if (s[i] != data[i]) {
|
||||
// Note: Since `data` never contains a '0' in positions [0,pos)
|
||||
// this will bailout once we have reached the end of `s`.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// A NUL-terminated string of `pos + 1` chars (the +1 is for the 0).
|
||||
char data[256];
|
||||
|
||||
// Invariant: < 256.
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
// A DataBuffer holding the string representation of a non-negative number.
|
||||
struct NumberBuffer : DataBuffer {
|
||||
// If possible, convert the string into a number.
|
||||
// Returns `true` in case of success, `false` in case of failure.
|
||||
bool asNumber(size_t* number) {
|
||||
int result;
|
||||
if (!my_strtoui(&result, data)) {
|
||||
return false;
|
||||
}
|
||||
*number = result;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// A DataBuffer holding the string representation of a unit. As of this
|
||||
// writing, we only support unit `kB`, which seems to be the only unit used in
|
||||
// `/proc/meminfo`.
|
||||
struct UnitBuffer : DataBuffer {
|
||||
// If possible, convert the string into a multiplier, e.g. `kB => 1024`.
|
||||
// Return `true` in case of success, `false` in case of failure.
|
||||
bool asMultiplier(size_t* multiplier) {
|
||||
if (*this == "kB") {
|
||||
*multiplier = 1024;
|
||||
return true;
|
||||
}
|
||||
// Other units don't seem to be specified/used.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// The state of the mini-parser.
|
||||
enum class State {
|
||||
// Reading the label, including the trailing ':'.
|
||||
Label,
|
||||
// Reading the number, ignoring any whitespace.
|
||||
Number,
|
||||
// Reading the unit, ignoring any whitespace.
|
||||
Unit,
|
||||
};
|
||||
|
||||
// A single measure being read from /proc/meminfo, e.g.
|
||||
// the total physical memory available on the system.
|
||||
struct Measure {
|
||||
Measure() : state(State::Label) {}
|
||||
// Reset the measure for a new read.
|
||||
void reset() {
|
||||
state = State::Label;
|
||||
label.reset();
|
||||
number.reset();
|
||||
unit.reset();
|
||||
}
|
||||
// Attempt to convert the measure into a number.
|
||||
// Return `true` if both the number and the multiplier could be
|
||||
// converted, `false` otherwise.
|
||||
// In case of overflow, produces the maximal possible `size_t`.
|
||||
bool asValue(size_t* result) {
|
||||
size_t numberAsSize = 0;
|
||||
if (!number.asNumber(&numberAsSize)) {
|
||||
return false;
|
||||
}
|
||||
size_t unitAsMultiplier = 0;
|
||||
if (!unit.asMultiplier(&unitAsMultiplier)) {
|
||||
return false;
|
||||
}
|
||||
if (numberAsSize * unitAsMultiplier >= numberAsSize) {
|
||||
*result = numberAsSize * unitAsMultiplier;
|
||||
} else {
|
||||
// Overflow. Unlikely, but just in case, let's return
|
||||
// the maximal possible value.
|
||||
*result = size_t(-1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// The label being read, e.g. `MemFree`. Does not include the trailing ':'.
|
||||
DataBuffer label;
|
||||
|
||||
// The number being read, e.g. "1024".
|
||||
NumberBuffer number;
|
||||
|
||||
// The unit being read, e.g. "kB".
|
||||
UnitBuffer unit;
|
||||
|
||||
// What we're reading at the moment.
|
||||
State state;
|
||||
};
|
||||
|
||||
// A value we wish to store for later processing.
|
||||
// e.g. to compute `AvailablePageFile`, we need to
|
||||
// store `CommitLimit` and `Committed_AS`.
|
||||
struct ValueStore {
|
||||
ValueStore() : value(0), found(false) {}
|
||||
size_t value;
|
||||
bool found;
|
||||
};
|
||||
ValueStore commitLimit;
|
||||
ValueStore committedAS;
|
||||
ValueStore memTotal;
|
||||
ValueStore swapTotal;
|
||||
|
||||
// The current measure.
|
||||
Measure measure;
|
||||
|
||||
for (size_t pos = 0; pos < size_t(bufferLen); ++pos) {
|
||||
const char c = buffer[pos];
|
||||
switch (measure.state) {
|
||||
case State::Label:
|
||||
if (c == ':') {
|
||||
// We have finished reading the label.
|
||||
measure.state = State::Number;
|
||||
} else {
|
||||
measure.label.append(c);
|
||||
}
|
||||
break;
|
||||
case State::Number:
|
||||
if (c == ' ') {
|
||||
// Ignore whitespace
|
||||
} else if ('0' <= c && c <= '9') {
|
||||
// Accumulate numbers.
|
||||
measure.number.append(c);
|
||||
} else {
|
||||
// We have jumped to the unit.
|
||||
measure.unit.append(c);
|
||||
measure.state = State::Unit;
|
||||
}
|
||||
break;
|
||||
case State::Unit:
|
||||
if (c == ' ') {
|
||||
// Ignore whitespace
|
||||
} else if (c == '\n') {
|
||||
// Flush line.
|
||||
// - If this one of the measures we're interested in, write it.
|
||||
// - Once we're done, reset the parser.
|
||||
auto Guard = MakeScopeExit([&measure]() { measure.reset(); });
|
||||
|
||||
struct PointOfInterest {
|
||||
// The label we're looking for, e.g. "MemTotal".
|
||||
const char* label;
|
||||
// If non-nullptr, store the value at this address.
|
||||
ValueStore* dest;
|
||||
// If other than Annotation::Count, write the value for this
|
||||
// annotation.
|
||||
Annotation annotation;
|
||||
};
|
||||
const PointOfInterest POINTS_OF_INTEREST[] = {
|
||||
{"MemTotal", &memTotal, Annotation::TotalPhysicalMemory},
|
||||
{"MemFree", nullptr, Annotation::AvailablePhysicalMemory},
|
||||
{"MemAvailable", nullptr, Annotation::AvailableVirtualMemory},
|
||||
{"SwapFree", nullptr, Annotation::AvailableSwapMemory},
|
||||
{"SwapTotal", &swapTotal, Annotation::Count},
|
||||
{"CommitLimit", &commitLimit, Annotation::Count},
|
||||
{"Committed_AS", &committedAS, Annotation::Count},
|
||||
};
|
||||
for (const auto& pointOfInterest : POINTS_OF_INTEREST) {
|
||||
if (measure.label == pointOfInterest.label) {
|
||||
size_t value;
|
||||
if (measure.asValue(&value)) {
|
||||
if (pointOfInterest.dest != nullptr) {
|
||||
pointOfInterest.dest->found = true;
|
||||
pointOfInterest.dest->value = value;
|
||||
}
|
||||
if (pointOfInterest.annotation != Annotation::Count) {
|
||||
WriteMemoryAnnotation(aTable, pointOfInterest.annotation,
|
||||
value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Otherwise, ignore.
|
||||
} else {
|
||||
measure.unit.append(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (commitLimit.found && committedAS.found) {
|
||||
// If available, attempt to determine the available virtual memory.
|
||||
// As `commitLimit` is not guaranteed to be larger than `committedAS`,
|
||||
// we return `0` in case the commit limit has already been exceeded.
|
||||
uint64_t availablePageFile = (committedAS.value <= commitLimit.value)
|
||||
? (commitLimit.value - committedAS.value)
|
||||
: 0;
|
||||
WriteMemoryAnnotation(aTable, Annotation::AvailablePageFile,
|
||||
availablePageFile);
|
||||
}
|
||||
if (memTotal.found && swapTotal.found) {
|
||||
// If available, attempt to determine the available virtual memory.
|
||||
WriteMemoryAnnotation(aTable, Annotation::TotalPageFile,
|
||||
memTotal.value + swapTotal.value);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void AnnotateMemoryStatus(AnnotationTable&) {
|
||||
static void WriteMemoryStatus(AnnotationWriter& aWriter) {
|
||||
// No memory data for other platforms yet.
|
||||
}
|
||||
|
||||
#endif // XP_WIN || XP_MACOSX || XP_LINUX || else
|
||||
#endif // XP_WIN || XP_MACOSX || else
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
|
@ -1342,6 +1052,7 @@ static void WriteAnnotationsForMainProcessCrash(PlatformWriter& pw,
|
|||
# endif
|
||||
#endif // XP_WIN
|
||||
|
||||
WriteMemoryStatus(writer);
|
||||
WriteMozCrashReason(writer);
|
||||
|
||||
char oomAllocationSizeBuffer[32] = "";
|
||||
|
@ -1637,6 +1348,9 @@ static void PrepareChildExceptionTimeAnnotations(
|
|||
apiData.OpenHandle(f);
|
||||
BinaryAnnotationWriter writer(apiData);
|
||||
|
||||
// ...and write out any annotations.
|
||||
WriteMemoryStatus(writer);
|
||||
|
||||
char oomAllocationSizeBuffer[32] = "";
|
||||
if (gOOMAllocationSize) {
|
||||
XP_STOA(gOOMAllocationSize, oomAllocationSizeBuffer);
|
||||
|
@ -2434,8 +2148,6 @@ static void MergeContentCrashAnnotations(AnnotationTable& aDst,
|
|||
|
||||
// Adds crash time, uptime and memory report annotations
|
||||
static void AddCommonAnnotations(AnnotationTable& aAnnotations) {
|
||||
AnnotateMemoryStatus(aAnnotations);
|
||||
|
||||
nsAutoCString crashTime;
|
||||
crashTime.AppendInt((uint64_t)time(nullptr));
|
||||
aAnnotations[Annotation::CrashTime] = crashTime;
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
add_task(async function run_test() {
|
||||
if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
|
||||
dump(
|
||||
"INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await do_content_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_OOM;
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
|
||||
// A list of pairs [annotation name, must be > 0]
|
||||
let annotations;
|
||||
switch (AppConstants.platform) {
|
||||
case "win":
|
||||
annotations = [
|
||||
["OOMAllocationSize", true],
|
||||
["SystemMemoryUsePercentage", false],
|
||||
["TotalVirtualMemory", true],
|
||||
["AvailableVirtualMemory", false],
|
||||
["TotalPageFile", false],
|
||||
["AvailablePageFile", false],
|
||||
["TotalPhysicalMemory", true],
|
||||
["AvailablePhysicalMemory", false],
|
||||
];
|
||||
break;
|
||||
case "linux":
|
||||
annotations = [
|
||||
["AvailablePageFile", false],
|
||||
["AvailablePhysicalMemory", false],
|
||||
["AvailableSwapMemory", false],
|
||||
["AvailableVirtualMemory", false],
|
||||
["TotalPageFile", false],
|
||||
["TotalPhysicalMemory", true],
|
||||
];
|
||||
break;
|
||||
case "macosx":
|
||||
annotations = [
|
||||
["AvailablePhysicalMemory", false],
|
||||
["AvailableSwapMemory", false],
|
||||
["PurgeablePhysicalMemory", false],
|
||||
["TotalPhysicalMemory", true],
|
||||
];
|
||||
break;
|
||||
default:
|
||||
annotations = [];
|
||||
}
|
||||
for (let [label, shouldBeGreaterThanZero] of annotations) {
|
||||
Assert.ok(label in extra, `Annotation ${label} is present`);
|
||||
|
||||
// All these annotations should represent non-negative numbers.
|
||||
// A few of them (e.g. physical memory) are guaranteed to be positive.
|
||||
if (shouldBeGreaterThanZero) {
|
||||
Assert.ok(Number(extra[label]) > 0);
|
||||
} else {
|
||||
Assert.ok(Number(extra[label]) >= 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
add_task(async function run_test() {
|
||||
if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
|
||||
dump(
|
||||
"INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_OOM;
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.ok("OOMAllocationSize" in extra);
|
||||
Assert.ok(Number(extra.OOMAllocationSize) > 0);
|
||||
Assert.ok("SystemMemoryUsePercentage" in extra);
|
||||
Assert.ok("TotalVirtualMemory" in extra);
|
||||
Assert.ok("AvailableVirtualMemory" in extra);
|
||||
Assert.ok("TotalPageFile" in extra);
|
||||
Assert.ok("AvailablePageFile" in extra);
|
||||
Assert.ok("TotalPhysicalMemory" in extra);
|
||||
Assert.ok("AvailablePhysicalMemory" in extra);
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
|
@ -15,7 +15,8 @@ support-files =
|
|||
[test_crash_after_js_large_allocation_failure.js]
|
||||
[test_crash_after_js_large_allocation_failure_reporting.js]
|
||||
[test_crash_oom.js]
|
||||
[test_oom_annotation.js]
|
||||
[test_oom_annotation_windows.js]
|
||||
skip-if = os != 'win'
|
||||
|
||||
[test_crash_abort.js]
|
||||
skip-if = os == 'win'
|
||||
|
|
Загрузка…
Ссылка в новой задаче