Bug 1007534 - Part 3: Submit about:memory data from the native crash client. r=ted

This commit is contained in:
David Major 2014-08-30 17:21:18 +12:00
parent 9111470b4f
commit 49ed056f7c
2 changed files with 122 additions and 11 deletions

View File

@ -41,8 +41,10 @@ enum SubmissionResult {Succeeded, Failed};
static auto_ptr<ofstream> gLogStream(nullptr);
static string gReporterDumpFile;
static string gExtraFile;
static string gMemoryFile;
static string kExtraDataExtension = ".extra";
static const char kExtraDataExtension[] = ".extra";
static const char kMemoryReportExtension[] = ".memory.json.gz";
void UIError(const string& message)
{
@ -257,20 +259,22 @@ static bool ReadConfig()
return true;
}
static string GetExtraDataFilename(const string& dumpfile)
static string
GetAdditionalFilename(const string& dumpfile, const char* extension)
{
string filename(dumpfile);
int dot = filename.rfind('.');
if (dot < 0)
return "";
filename.replace(dot, filename.length() - dot, kExtraDataExtension);
filename.replace(dot, filename.length() - dot, extension);
return filename;
}
static bool MoveCrashData(const string& toDir,
string& dumpfile,
string& extrafile)
string& extrafile,
string& memoryfile)
{
if (!UIEnsurePathExists(toDir)) {
UIError(gStrings[ST_ERROR_CREATEDUMPDIR]);
@ -279,6 +283,7 @@ static bool MoveCrashData(const string& toDir,
string newDump = toDir + UI_DIR_SEPARATOR + Basename(dumpfile);
string newExtra = toDir + UI_DIR_SEPARATOR + Basename(extrafile);
string newMemory = toDir + UI_DIR_SEPARATOR + Basename(memoryfile);
if (!UIMoveFile(dumpfile, newDump)) {
UIError(gStrings[ST_ERROR_DUMPFILEMOVE]);
@ -290,6 +295,15 @@ static bool MoveCrashData(const string& toDir,
return false;
}
if (!memoryfile.empty()) {
// Ignore errors from moving the memory file
if (!UIMoveFile(memoryfile, newMemory)) {
UIDeleteFile(memoryfile);
newMemory.erase();
}
memoryfile = newMemory;
}
dumpfile = newDump;
extrafile = newExtra;
@ -369,6 +383,8 @@ void DeleteDump()
UIDeleteFile(gReporterDumpFile);
if (!gExtraFile.empty())
UIDeleteFile(gExtraFile);
if (!gMemoryFile.empty())
UIDeleteFile(gMemoryFile);
}
}
@ -498,7 +514,7 @@ int main(int argc, char** argv)
// no dump file specified, run the default UI
UIShowDefaultUI();
} else {
gExtraFile = GetExtraDataFilename(gReporterDumpFile);
gExtraFile = GetAdditionalFilename(gReporterDumpFile, kExtraDataExtension);
if (gExtraFile.empty()) {
UIError(gStrings[ST_ERROR_BADARGUMENTS]);
return 0;
@ -509,6 +525,12 @@ int main(int argc, char** argv)
return 0;
}
gMemoryFile = GetAdditionalFilename(gReporterDumpFile,
kMemoryReportExtension);
if (!UIFileExists(gMemoryFile)) {
gMemoryFile.erase();
}
StringTable queryParameters;
if (!ReadStringsFromFile(gExtraFile, queryParameters, true)) {
UIError(gStrings[ST_ERROR_EXTRAFILEREAD]);
@ -582,7 +604,8 @@ int main(int argc, char** argv)
}
string pendingDir = gSettingsPath + UI_DIR_SEPARATOR + "pending";
if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile)) {
if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile,
gMemoryFile)) {
return 0;
}
@ -639,6 +662,9 @@ int main(int argc, char** argv)
StringTable files;
files["upload_file_minidump"] = gReporterDumpFile;
if (!gMemoryFile.empty()) {
files["memory_report"] = gMemoryFile;
}
if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs))
DeleteDump();

View File

@ -107,6 +107,7 @@ namespace CrashReporter {
#ifdef XP_WIN32
typedef wchar_t XP_CHAR;
typedef std::wstring xpstring;
#define XP_TEXT(x) L##x
#define CONVERT_XP_CHAR_TO_UTF16(x) x
#define XP_STRLEN(x) wcslen(x)
#define my_strlen strlen
@ -126,6 +127,7 @@ typedef std::wstring xpstring;
#else
typedef char XP_CHAR;
typedef std::string xpstring;
#define XP_TEXT(x) x
#define CONVERT_XP_CHAR_TO_UTF16(x) NS_ConvertUTF8toUTF16(x)
#define CRASH_REPORTER_FILENAME "crashreporter"
#define PATH_SEPARATOR "/"
@ -143,17 +145,17 @@ typedef std::string xpstring;
#define sys_close close
#define sys_fork fork
#define sys_open open
#define sys_read read
#define sys_write write
#endif
#endif // XP_WIN32
#ifndef XP_LINUX
static const XP_CHAR dumpFileExtension[] = {'.', 'd', 'm', 'p',
'\0'}; // .dmp
static const XP_CHAR dumpFileExtension[] = XP_TEXT(".dmp");
#endif
static const XP_CHAR extraFileExtension[] = {'.', 'e', 'x', 't',
'r', 'a', '\0'}; // .extra
static const XP_CHAR extraFileExtension[] = XP_TEXT(".extra");
static const XP_CHAR memoryReportExtension[] = XP_TEXT(".memory.json.gz");
static const char kCrashMainID[] = "crash.main.1\n";
@ -209,7 +211,6 @@ static const char kOOMAllocationSizeParameter[] = "OOMAllocationSize=";
static const int kOOMAllocationSizeParameterLen =
sizeof(kOOMAllocationSizeParameter)-1;
#ifdef XP_WIN32
static const char kSysMemoryParameter[] = "SystemMemoryUsePercentage=";
static const int kSysMemoryParameterLen = sizeof(kSysMemoryParameter)-1;
@ -257,6 +258,10 @@ static const int kBreakpadReserveSizeParameterLen =
sizeof(kBreakpadReserveSizeParameter)-1;
#endif
static const char kMemoryReportParameter[] = "ContainsMemoryReport=1\n";
static const int kMemoryReportParameterLen =
sizeof(kMemoryReportParameter)-1;
// this holds additional data sent via the API
static Mutex* crashReporterAPILock;
static Mutex* notesFieldLock;
@ -463,6 +468,56 @@ void AnnotateOOMAllocationSize(size_t size)
gOOMAllocationSize = size;
}
#ifndef XP_WIN
// Like Windows CopyFile for *nix
bool copy_file(const char* from, const char* to)
{
const int kBufSize = 4096;
int fdfrom = sys_open(from, O_RDONLY, 0);
if (fdfrom < 0) {
return false;
}
bool ok = false;
int fdto = sys_open(to, O_WRONLY | O_CREAT, 0666);
if (fdto < 0) {
sys_close(fdfrom);
return false;
}
char buf[kBufSize];
while (true) {
int r = sys_read(fdfrom, buf, kBufSize);
if (r == 0) {
ok = true;
break;
}
if (r < 0) {
break;
}
char* wbuf = buf;
while (r) {
int w = sys_write(fdto, wbuf, r);
if (w > 0) {
r -= w;
wbuf += w;
} else if (errno != EINTR) {
break;
}
}
if (r) {
break;
}
}
sys_close(fdfrom);
sys_close(fdto);
return ok;
}
#endif
bool MinidumpCallback(
#ifdef XP_LINUX
const MinidumpDescriptor& descriptor,
@ -504,6 +559,27 @@ bool MinidumpCallback(
#endif
Concat(p, extraFileExtension, &size);
static XP_CHAR memoryReportLocalPath[XP_PATH_MAX];
size = XP_PATH_MAX;
#ifndef XP_LINUX
p = Concat(memoryReportLocalPath, dump_path, &size);
p = Concat(p, XP_PATH_SEPARATOR, &size);
p = Concat(p, minidump_id, &size);
#else
p = Concat(memoryReportLocalPath, descriptor.path(), &size);
// Skip back past the .dmp extension
p -= 4;
#endif
Concat(p, memoryReportExtension, &size);
if (memoryReportPath) {
#ifdef XP_WIN
CopyFile(memoryReportPath, memoryReportLocalPath, false);
#else
copy_file(memoryReportPath, memoryReportLocalPath);
#endif
}
if (headlessClient) {
// Leave a marker indicating that there was a crash.
#if defined(XP_WIN32)
@ -721,6 +797,11 @@ bool MinidumpCallback(
&nBytes, nullptr);
WriteFile(hFile, "\n", 1, &nBytes, nullptr);
}
if (memoryReportPath) {
WriteFile(hFile, kMemoryReportParameter,
kMemoryReportParameterLen, &nBytes, nullptr);
}
CloseHandle(hFile);
}
}
@ -793,6 +874,10 @@ bool MinidumpCallback(
oomAllocationSizeBufferLen);
unused << sys_write(fd, "\n", 1);
}
if (memoryReportPath) {
unused << sys_write(fd, kMemoryReportParameter,
kMemoryReportParameterLen);
}
sys_close(fd);
}
}