mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 389548 - cvs removing toolkit/airbag
This commit is contained in:
parent
e95c66ecef
commit
87fe4abc1e
@ -1,110 +0,0 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla Airbag integration
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = crashreporter
|
||||
LIBXUL_LIBRARY = 1
|
||||
LIBRARY_NAME = exception_handler_s
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
string \
|
||||
xulapp \
|
||||
$(NULL)
|
||||
|
||||
DIRS = \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
DIRS += airbag/src/common/windows \
|
||||
airbag/src/client/windows \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),Darwin)
|
||||
CMMSRCS = mac_utils.mm
|
||||
|
||||
DIRS += \
|
||||
airbag/src/common \
|
||||
airbag/src/common/mac \
|
||||
airbag/src/client \
|
||||
airbag/src/client/mac/handler \
|
||||
airbag/src/tools/mac/dump_syms \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
# there's no define for this normally
|
||||
DEFINES += -DXP_LINUX
|
||||
DIRS += \
|
||||
airbag/src/common \
|
||||
airbag/src/common/linux \
|
||||
airbag/src/client \
|
||||
airbag/src/client/linux/handler \
|
||||
airbag/src/tools/linux/dump_syms \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
DIRS += client
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/airbag/src
|
||||
DEFINES += -DUNICODE -D_UNICODE
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsICrashReporter.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsAirbagExceptionHandler.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsAirbagExceptionHandler.cpp \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
@ -1,47 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Breakpad integration
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef toolkit_breakpad_mac_utils_h__
|
||||
#define toolkit_breakpad_mac_utils_h__
|
||||
|
||||
/*
|
||||
* Look up a setting in our user defaults indicating
|
||||
* that the user wants to see the OS crash reporting dialog.
|
||||
*/
|
||||
bool PassToOSCrashReporter();
|
||||
|
||||
#endif /* toolkit_breakpad_mac_utils_h__ */
|
@ -1,50 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Breakpad integration
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include "mac_utils.h"
|
||||
|
||||
bool PassToOSCrashReporter()
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL osCrashReporter = [userDefaults boolForKey:@"OSCrashReporter"];
|
||||
[pool release];
|
||||
|
||||
return osCrashReporter == YES;
|
||||
}
|
@ -1,644 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Airbag integration
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAirbagExceptionHandler.h"
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include "client/windows/handler/exception_handler.h"
|
||||
#include <string.h>
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "client/mac/handler/exception_handler.h"
|
||||
#include <string>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "mac_utils.h"
|
||||
#elif defined(XP_LINUX)
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error "Not yet implemented for this platform"
|
||||
#endif // defined(XP_WIN32)
|
||||
|
||||
#ifndef HAVE_CPP_2BYTE_WCHAR_T
|
||||
#error "This code expects a 2 byte wchar_t. You should --disable-airbag."
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <prenv.h>
|
||||
#include <prio.h>
|
||||
#include "nsDebug.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
namespace CrashReporter {
|
||||
|
||||
#ifdef XP_WIN32
|
||||
typedef wchar_t XP_CHAR;
|
||||
#define TO_NEW_XP_CHAR(x) ToNewUnicode(x)
|
||||
#define CONVERT_UTF16_TO_XP_CHAR(x) x
|
||||
#define XP_STRLEN(x) wcslen(x)
|
||||
#define CRASH_REPORTER_FILENAME "crashreporter.exe"
|
||||
#define PATH_SEPARATOR "\\"
|
||||
#define XP_PATH_SEPARATOR L"\\"
|
||||
// sort of arbitrary, but MAX_PATH is kinda small
|
||||
#define XP_PATH_MAX 4096
|
||||
// "<reporter path>" "<minidump path>"
|
||||
#define CMDLINE_SIZE ((XP_PATH_MAX * 2) + 6)
|
||||
#else
|
||||
typedef char XP_CHAR;
|
||||
#define TO_NEW_XP_CHAR(x) ToNewUTF8String(x)
|
||||
#define CONVERT_UTF16_TO_XP_CHAR(x) NS_ConvertUTF16toUTF8(x)
|
||||
#define XP_STRLEN(x) strlen(x)
|
||||
#define CRASH_REPORTER_FILENAME "crashreporter"
|
||||
#define PATH_SEPARATOR "/"
|
||||
#define XP_PATH_SEPARATOR "/"
|
||||
#define XP_PATH_MAX PATH_MAX
|
||||
#endif // XP_WIN32
|
||||
|
||||
static const XP_CHAR dumpFileExtension[] = {'.', 'd', 'm', 'p',
|
||||
'\0'}; // .dmp
|
||||
static const XP_CHAR extraFileExtension[] = {'.', 'e', 'x', 't',
|
||||
'r', 'a', '\0'}; // .extra
|
||||
|
||||
static google_breakpad::ExceptionHandler* gExceptionHandler = nsnull;
|
||||
|
||||
static XP_CHAR* crashReporterPath;
|
||||
|
||||
// if this is false, we don't launch the crash reporter
|
||||
static bool doReport = true;
|
||||
|
||||
// if this is true, we pass the exception on to the OS crash reporter
|
||||
static bool showOSCrashReporter = false;
|
||||
|
||||
// this holds additional data sent via the API
|
||||
static nsDataHashtable<nsCStringHashKey,nsCString>* crashReporterAPIData_Hash;
|
||||
static nsCString* crashReporterAPIData = nsnull;
|
||||
|
||||
static XP_CHAR*
|
||||
Concat(XP_CHAR* str, const XP_CHAR* toAppend, int* size)
|
||||
{
|
||||
int appendLen = XP_STRLEN(toAppend);
|
||||
if (appendLen >= *size) appendLen = *size - 1;
|
||||
|
||||
memcpy(str, toAppend, appendLen * sizeof(XP_CHAR));
|
||||
str += appendLen;
|
||||
*str = '\0';
|
||||
*size -= appendLen;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
const XP_CHAR* minidump_id,
|
||||
void* context,
|
||||
#ifdef XP_WIN32
|
||||
EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion,
|
||||
#endif
|
||||
bool succeeded)
|
||||
{
|
||||
bool returnValue = showOSCrashReporter ? false : succeeded;
|
||||
|
||||
XP_CHAR minidumpPath[XP_PATH_MAX];
|
||||
int size = XP_PATH_MAX;
|
||||
XP_CHAR* p = Concat(minidumpPath, dump_path, &size);
|
||||
p = Concat(p, XP_PATH_SEPARATOR, &size);
|
||||
p = Concat(p, minidump_id, &size);
|
||||
Concat(p, dumpFileExtension, &size);
|
||||
|
||||
XP_CHAR extraDataPath[XP_PATH_MAX];
|
||||
size = XP_PATH_MAX;
|
||||
p = Concat(extraDataPath, dump_path, &size);
|
||||
p = Concat(p, XP_PATH_SEPARATOR, &size);
|
||||
p = Concat(p, minidump_id, &size);
|
||||
Concat(p, extraFileExtension, &size);
|
||||
|
||||
#ifdef XP_WIN32
|
||||
XP_CHAR cmdLine[CMDLINE_SIZE];
|
||||
size = CMDLINE_SIZE;
|
||||
p = Concat(cmdLine, L"\"", &size);
|
||||
p = Concat(p, crashReporterPath, &size);
|
||||
p = Concat(p, L"\" \"", &size);
|
||||
p = Concat(p, minidumpPath, &size);
|
||||
Concat(p, L"\"", &size);
|
||||
|
||||
if (!crashReporterAPIData->IsEmpty()) {
|
||||
// write out API data
|
||||
HANDLE hFile = CreateFile(extraDataPath, GENERIC_WRITE, 0,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if(hFile != INVALID_HANDLE_VALUE) {
|
||||
DWORD nBytes;
|
||||
WriteFile(hFile, crashReporterAPIData->get(),
|
||||
crashReporterAPIData->Length(), &nBytes, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!doReport) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_SHOWNORMAL;
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
if (CreateProcess(NULL, (LPWSTR)cmdLine, NULL, NULL, FALSE, 0,
|
||||
NULL, NULL, &si, &pi)) {
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
}
|
||||
// we're not really in a position to do anything if the CreateProcess fails
|
||||
TerminateProcess(GetCurrentProcess(), 1);
|
||||
#elif defined(XP_UNIX)
|
||||
if (!crashReporterAPIData->IsEmpty()) {
|
||||
// write out API data
|
||||
int fd = open(extraDataPath,
|
||||
O_WRONLY | O_CREAT | O_TRUNC,
|
||||
0666);
|
||||
|
||||
if (fd != -1) {
|
||||
// not much we can do in case of error
|
||||
write(fd, crashReporterAPIData->get(), crashReporterAPIData->Length());
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!doReport) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid == -1)
|
||||
return false;
|
||||
else if (pid == 0) {
|
||||
(void) execl(crashReporterPath,
|
||||
crashReporterPath, minidumpPath, (char*)0);
|
||||
_exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
|
||||
const char* aServerURL)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (gExceptionHandler)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
const char *envvar = PR_GetEnv("MOZ_CRASHREPORTER_DISABLE");
|
||||
if (envvar && *envvar)
|
||||
return NS_OK;
|
||||
|
||||
// this environment variable prevents us from launching
|
||||
// the crash reporter client
|
||||
envvar = PR_GetEnv("MOZ_CRASHREPORTER_NO_REPORT");
|
||||
if (envvar && *envvar)
|
||||
doReport = false;
|
||||
|
||||
// allocate our strings
|
||||
crashReporterAPIData = new nsCString();
|
||||
NS_ENSURE_TRUE(crashReporterAPIData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
crashReporterAPIData_Hash =
|
||||
new nsDataHashtable<nsCStringHashKey,nsCString>();
|
||||
NS_ENSURE_TRUE(crashReporterAPIData_Hash, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = crashReporterAPIData_Hash->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// locate crashreporter executable
|
||||
nsCOMPtr<nsIFile> exePath;
|
||||
rv = aXREDirectory->Clone(getter_AddRefs(exePath));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
exePath->Append(NS_LITERAL_STRING("crashreporter.app"));
|
||||
exePath->Append(NS_LITERAL_STRING("Contents"));
|
||||
exePath->Append(NS_LITERAL_STRING("MacOS"));
|
||||
#endif
|
||||
|
||||
exePath->Append(NS_LITERAL_STRING(CRASH_REPORTER_FILENAME));
|
||||
|
||||
nsString crashReporterPath_temp;
|
||||
exePath->GetPath(crashReporterPath_temp);
|
||||
|
||||
crashReporterPath = TO_NEW_XP_CHAR(crashReporterPath_temp);
|
||||
|
||||
// get temp path to use for minidump path
|
||||
nsString tempPath;
|
||||
#if defined(XP_WIN32)
|
||||
// first figure out buffer size
|
||||
int pathLen = GetTempPath(0, NULL);
|
||||
if (pathLen == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
tempPath.SetLength(pathLen);
|
||||
GetTempPath(pathLen, (LPWSTR)tempPath.BeginWriting());
|
||||
#elif defined(XP_MACOSX)
|
||||
FSRef fsRef;
|
||||
OSErr err = FSFindFolder(kUserDomain, kTemporaryFolderType,
|
||||
kCreateFolder, &fsRef);
|
||||
if (err != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char path[PATH_MAX];
|
||||
OSStatus status = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
|
||||
if (status != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
tempPath = NS_ConvertUTF8toUTF16(path);
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
// we assume it's always /tmp on unix systems
|
||||
tempPath = NS_LITERAL_STRING("/tmp/");
|
||||
#else
|
||||
//XXX: implement get temp path on other platforms
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
||||
// now set the exception handler
|
||||
gExceptionHandler = new google_breakpad::
|
||||
ExceptionHandler(CONVERT_UTF16_TO_XP_CHAR(tempPath).get(),
|
||||
nsnull,
|
||||
MinidumpCallback,
|
||||
nsnull,
|
||||
#if defined(XP_WIN32)
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL);
|
||||
#else
|
||||
true);
|
||||
#endif
|
||||
|
||||
if (!gExceptionHandler)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// store server URL with the API data
|
||||
if (aServerURL)
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("ServerURL"),
|
||||
nsDependentCString(aServerURL));
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// On OS X, many testers like to see the OS crash reporting dialog
|
||||
// since it offers immediate stack traces. We allow them to set
|
||||
// a default to pass exceptions to the OS handler.
|
||||
showOSCrashReporter = PassToOSCrashReporter();
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SetMinidumpPath(const nsAString& aPath)
|
||||
{
|
||||
if (!gExceptionHandler)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
gExceptionHandler->set_dump_path(CONVERT_UTF16_TO_XP_CHAR(aPath).BeginReading());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
WriteDataToFile(nsIFile* aFile, const nsACString& data)
|
||||
{
|
||||
nsCAutoString filename;
|
||||
nsresult rv = aFile->GetNativePath(filename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRFileDesc* fd = PR_Open(filename.get(), PR_WRONLY | PR_CREATE_FILE, 00600);
|
||||
NS_ENSURE_TRUE(fd, NS_ERROR_FAILURE);
|
||||
|
||||
rv = NS_OK;
|
||||
if (PR_Write(fd, data.Data(), data.Length()) == -1) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
PR_Close(fd);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetFileContents(nsIFile* aFile, nsACString& data)
|
||||
{
|
||||
nsCAutoString filename;
|
||||
nsresult rv = aFile->GetNativePath(filename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRFileDesc* fd = PR_Open(filename.get(), PR_RDONLY, 0);
|
||||
NS_ENSURE_TRUE(fd, NS_ERROR_FILE_NOT_FOUND);
|
||||
|
||||
rv = NS_OK;
|
||||
PRInt32 filesize = PR_Available(fd);
|
||||
if (filesize <= 0) {
|
||||
rv = NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
else {
|
||||
data.SetLength(filesize);
|
||||
if (PR_Read(fd, data.BeginWriting(), filesize) == -1) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
PR_Close(fd);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Function typedef for initializing a piece of data that we
|
||||
// don't already have.
|
||||
typedef nsresult (*InitDataFunc)(nsACString&);
|
||||
|
||||
// Attempt to read aFile's contents into aContents, if aFile
|
||||
// does not exist, create it and initialize its contents
|
||||
// by calling aInitFunc for the data.
|
||||
static nsresult
|
||||
GetOrInit(nsILocalFile* aDir, const nsAString& filename,
|
||||
nsACString& aContents, InitDataFunc aInitFunc)
|
||||
{
|
||||
PRBool exists;
|
||||
|
||||
nsCOMPtr<nsIFile> dataFile;
|
||||
nsresult rv = aDir->Clone(getter_AddRefs(dataFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dataFile->Append(filename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dataFile->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!exists) {
|
||||
// get the initial value and write it to the file
|
||||
rv = aInitFunc(aContents);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = WriteDataToFile(dataFile, aContents);
|
||||
}
|
||||
else {
|
||||
// just get the file's contents
|
||||
rv = GetFileContents(dataFile, aContents);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Generate a unique user ID. We're using a GUID form,
|
||||
// but not jumping through hoops to make it cryptographically
|
||||
// secure. We just want it to distinguish unique users.
|
||||
static nsresult
|
||||
InitUserID(nsACString& aUserID)
|
||||
{
|
||||
nsID id;
|
||||
|
||||
// copied shamelessly from nsUUIDGenerator.cpp
|
||||
#if defined(XP_WIN)
|
||||
HRESULT hr = CoCreateGuid((GUID*)&id);
|
||||
if (NS_FAILED(hr))
|
||||
return NS_ERROR_FAILURE;
|
||||
#elif defined(XP_MACOSX)
|
||||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
if (!uuid)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
|
||||
memcpy(&id, &bytes, sizeof(nsID));
|
||||
|
||||
CFRelease(uuid);
|
||||
#else
|
||||
// UNIX or some such thing
|
||||
id.m0 = random();
|
||||
id.m1 = random();
|
||||
id.m2 = random();
|
||||
*reinterpret_cast<PRUint32*>(&id.m3[0]) = random();
|
||||
*reinterpret_cast<PRUint32*>(&id.m3[4]) = random();
|
||||
#endif
|
||||
|
||||
nsCAutoString id_str(id.ToString());
|
||||
aUserID = Substring(id_str, 1, id_str.Length()-2);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Init the "install time" data. We're taking an easy way out here
|
||||
// and just setting this to "the time when this version was first run".
|
||||
static nsresult
|
||||
InitInstallTime(nsACString& aInstallTime)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
char buf[16];
|
||||
sprintf(buf, "%ld", t);
|
||||
aInstallTime = buf;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Annotate the crash report with a Unique User ID.
|
||||
// TODO: also add time since install, and time since last crash.
|
||||
// (bug 376720 and bug 376721)
|
||||
// If any piece of data doesn't exist, initialize it first.
|
||||
nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
|
||||
const nsACString& aBuildID)
|
||||
{
|
||||
nsresult rv = aAppDataDirectory->Append(NS_LITERAL_STRING("Crash Reports"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString data;
|
||||
if(NS_SUCCEEDED(GetOrInit(aAppDataDirectory, NS_LITERAL_STRING("UserID"),
|
||||
data, InitUserID)))
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("UserID"), data);
|
||||
|
||||
if(NS_SUCCEEDED(GetOrInit(aAppDataDirectory,
|
||||
NS_LITERAL_STRING("InstallTime") +
|
||||
NS_ConvertASCIItoUTF16(aBuildID),
|
||||
data, InitInstallTime)))
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("InstallTime"), data);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult UnsetExceptionHandler()
|
||||
{
|
||||
// do this here in the unlikely case that we succeeded in allocating
|
||||
// our strings but failed to allocate gExceptionHandler.
|
||||
if (crashReporterAPIData_Hash) {
|
||||
delete crashReporterAPIData_Hash;
|
||||
crashReporterAPIData_Hash = nsnull;
|
||||
}
|
||||
if (crashReporterPath) {
|
||||
NS_Free(crashReporterPath);
|
||||
crashReporterPath = nsnull;
|
||||
}
|
||||
|
||||
if (!gExceptionHandler)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
delete gExceptionHandler;
|
||||
gExceptionHandler = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void ReplaceChar(nsCString& str, const nsACString& character,
|
||||
const nsACString& replacement)
|
||||
{
|
||||
nsCString::const_iterator start, end;
|
||||
|
||||
str.BeginReading(start);
|
||||
str.EndReading(end);
|
||||
|
||||
while (FindInReadable(character, start, end)) {
|
||||
PRInt32 pos = end.size_backward();
|
||||
str.Replace(pos - 1, 1, replacement);
|
||||
|
||||
str.BeginReading(start);
|
||||
start.advance(pos + replacement.Length() - 1);
|
||||
str.EndReading(end);
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool DoFindInReadable(const nsACString& str, const nsACString& value)
|
||||
{
|
||||
nsACString::const_iterator start, end;
|
||||
str.BeginReading(start);
|
||||
str.EndReading(end);
|
||||
|
||||
return FindInReadable(value, start, end);
|
||||
}
|
||||
|
||||
static PLDHashOperator PR_CALLBACK EnumerateEntries(const nsACString& key,
|
||||
nsCString entry,
|
||||
void* userData)
|
||||
{
|
||||
crashReporterAPIData->Append(key + NS_LITERAL_CSTRING("=") + entry +
|
||||
NS_LITERAL_CSTRING("\n"));
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data)
|
||||
{
|
||||
if (!gExceptionHandler)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (DoFindInReadable(key, NS_LITERAL_CSTRING("=")) ||
|
||||
DoFindInReadable(key, NS_LITERAL_CSTRING("\n")))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (DoFindInReadable(data, NS_LITERAL_CSTRING("\0")))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCString escapedData(data);
|
||||
|
||||
// escape backslashes
|
||||
ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"),
|
||||
NS_LITERAL_CSTRING("\\\\"));
|
||||
// escape newlines
|
||||
ReplaceChar(escapedData, NS_LITERAL_CSTRING("\n"),
|
||||
NS_LITERAL_CSTRING("\\n"));
|
||||
|
||||
nsresult rv = crashReporterAPIData_Hash->Put(key, escapedData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// now rebuild the file contents
|
||||
crashReporterAPIData->Truncate(0);
|
||||
crashReporterAPIData_Hash->EnumerateRead(EnumerateEntries,
|
||||
crashReporterAPIData);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SetRestartArgs(int argc, char **argv)
|
||||
{
|
||||
if (!gExceptionHandler)
|
||||
return NS_OK;
|
||||
|
||||
int i;
|
||||
nsCAutoString envVar;
|
||||
char *env;
|
||||
for (i = 0; i < argc; i++) {
|
||||
envVar = "MOZ_CRASHREPORTER_RESTART_ARG_";
|
||||
envVar.AppendInt(i);
|
||||
envVar += "=";
|
||||
envVar += argv[i];
|
||||
|
||||
// PR_SetEnv() wants the string to be available for the lifetime
|
||||
// of the app, so dup it here
|
||||
env = ToNewCString(envVar);
|
||||
if (!env)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PR_SetEnv(env);
|
||||
}
|
||||
|
||||
// make sure the arg list is terminated
|
||||
envVar = "MOZ_CRASHREPORTER_RESTART_ARG_";
|
||||
envVar.AppendInt(i);
|
||||
envVar += "=";
|
||||
|
||||
// PR_SetEnv() wants the string to be available for the lifetime
|
||||
// of the app, so dup it here
|
||||
env = ToNewCString(envVar);
|
||||
if (!env)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PR_SetEnv(env);
|
||||
|
||||
// make sure we save the info in XUL_APP_FILE for the reporter
|
||||
const char *appfile = PR_GetEnv("XUL_APP_FILE");
|
||||
if (appfile && *appfile) {
|
||||
envVar = "MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE=";
|
||||
envVar += appfile;
|
||||
env = ToNewCString(envVar);
|
||||
PR_SetEnv(env);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
} // namespace CrashReporter
|
@ -1,56 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Airbag integration
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsAirbagExceptionHandler_h__
|
||||
#define nsAirbagExceptionHandler_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
namespace CrashReporter {
|
||||
nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
|
||||
const char* aServerURL);
|
||||
nsresult SetMinidumpPath(const nsAString& aPath);
|
||||
nsresult UnsetExceptionHandler();
|
||||
nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data);
|
||||
nsresult SetRestartArgs(int argc, char **argv);
|
||||
nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
|
||||
const nsACString& aBuildID);
|
||||
}
|
||||
|
||||
#endif /* nsAirbagExceptionHandler_h__ */
|
@ -1,62 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Breakpad Integration.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* Provides access to crash reporting functionality.
|
||||
* @status UNSTABLE - This interface is not frozen and will probably change in
|
||||
* future releases.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(da7020ad-fad4-443e-b02b-c5cc9d482e2f)]
|
||||
interface nsICrashReporter : nsISupports
|
||||
{
|
||||
/**
|
||||
* Add some extra data to be submitted with a crash report.
|
||||
* @param key
|
||||
* Name of the data to be added.
|
||||
* @param data
|
||||
* Data to be added.
|
||||
*
|
||||
* @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
|
||||
* @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
|
||||
* Invalid characters for key are '=' and
|
||||
* '\n'. Invalid character for data is '\0'.
|
||||
*/
|
||||
void annotateCrashReport(in ACString key, in ACString data);
|
||||
};
|
@ -1,100 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla Breakpad integration.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifndef MOZ_ENABLE_LIBXUL
|
||||
PROGRAM = TestCrashReporterAPI$(BIN_SUFFIX)
|
||||
|
||||
CPPSRCS = TestCrashReporterAPI.cpp
|
||||
endif
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
string \
|
||||
crashreporter \
|
||||
$(NULL)
|
||||
|
||||
LIBS = \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(XPCOM_GLUE_LDOPTS) \
|
||||
$(XPCOM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(DEPTH)/toolkit/airbag/$(LIB_PREFIX)exception_handler_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
LIBS += \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/client/windows/handler/$(LIB_PREFIX)exception_handler_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/common/windows/$(LIB_PREFIX)breakpad_windows_common_s.$(LIB_SUFFIX)
|
||||
LIBS += $(call expand_libname shell32)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,ole32)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),Darwin)
|
||||
OS_LIBS += -framework Cocoa -lcrypto
|
||||
LIBS += \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/client/$(LIB_PREFIX)minidump_file_writer_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/client/mac/handler/$(LIB_PREFIX)exception_handler_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/common/$(LIB_PREFIX)breakpad_common_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/common/mac/$(LIB_PREFIX)breakpad_mac_common_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/../airbag/src/common/mac/
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
LIBS += \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/client/linux/handler/$(LIB_PREFIX)exception_handler_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/client/$(LIB_PREFIX)minidump_file_writer_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/common/$(LIB_PREFIX)breakpad_common_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/toolkit/airbag/airbag/src/common/linux/$(LIB_PREFIX)breakpad_linux_common_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifndef MOZ_ENABLE_LIBXUL
|
||||
check:: $(PROGRAM)
|
||||
$(RUN_TEST_PROGRAM) $(DIST)/bin/TestCrashReporterAPI
|
||||
endif
|
@ -1,166 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Breakpad integration
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prenv.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
#include "nsAirbagExceptionHandler.h"
|
||||
#include "nsICrashReporter.h"
|
||||
|
||||
#define mu_assert(message, test) do { if (NS_FAILED(test)) \
|
||||
return message; } while (0)
|
||||
#define mu_assert_failure(message, test) do { if (NS_SUCCEEDED(test)) \
|
||||
return message; } while (0)
|
||||
#define mu_run_test(test) do { char *message = test(); tests_run++; \
|
||||
if (message) return message; } while (0)
|
||||
int tests_run;
|
||||
|
||||
char *
|
||||
test_init_exception_handler()
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> lf;
|
||||
// we don't plan on launching the crash reporter in this app anyway,
|
||||
// so it's ok to pass a bogus nsILocalFile
|
||||
mu_assert("NS_NewNativeLocalFile", NS_NewNativeLocalFile(EmptyCString(),
|
||||
PR_TRUE,
|
||||
getter_AddRefs(lf)));
|
||||
|
||||
mu_assert("CrashReporter::SetExceptionHandler",
|
||||
CrashReporter::SetExceptionHandler(lf, nsnull));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
test_set_minidump_path()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> directoryService =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
|
||||
mu_assert("do_GetService", rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> currentDirectory;
|
||||
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsILocalFile),
|
||||
getter_AddRefs(currentDirectory));
|
||||
mu_assert("directoryService->Get", rv);
|
||||
|
||||
nsAutoString currentDirectoryPath;
|
||||
rv = currentDirectory->GetPath(currentDirectoryPath);
|
||||
mu_assert("currentDirectory->GetPath", rv);
|
||||
|
||||
mu_assert("CrashReporter::SetMinidumpPath",
|
||||
CrashReporter::SetMinidumpPath(currentDirectoryPath));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
test_annotate_crash_report_basic()
|
||||
{
|
||||
mu_assert("CrashReporter::AnnotateCrashReport: basic",
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test"),
|
||||
NS_LITERAL_CSTRING("some data")));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
test_annotate_crash_report_invalid_equals()
|
||||
{
|
||||
mu_assert_failure("CrashReporter::AnnotateCrashReport: invalid = in key",
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test=something"),
|
||||
NS_LITERAL_CSTRING("some data")));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
test_annotate_crash_report_invalid_cr()
|
||||
{
|
||||
mu_assert_failure("CrashReporter::AnnotateCrashReport: invalid \n in key",
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test\nsomething"),
|
||||
NS_LITERAL_CSTRING("some data")));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
test_unset_exception_handler()
|
||||
{
|
||||
mu_assert("CrashReporter::UnsetExceptionHandler",
|
||||
CrashReporter::UnsetExceptionHandler());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* all_tests()
|
||||
{
|
||||
mu_run_test(test_init_exception_handler);
|
||||
mu_run_test(test_set_minidump_path);
|
||||
mu_run_test(test_annotate_crash_report_basic);
|
||||
mu_run_test(test_annotate_crash_report_invalid_equals);
|
||||
mu_run_test(test_annotate_crash_report_invalid_cr);
|
||||
mu_run_test(test_unset_exception_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
NS_InitXPCOM2(nsnull, nsnull, nsnull);
|
||||
|
||||
PR_SetEnv("MOZ_CRASHREPORTER=1");
|
||||
|
||||
char* result = all_tests();
|
||||
if (result != 0) {
|
||||
printf("FAIL: %s\n", result);
|
||||
}
|
||||
else {
|
||||
printf("ALL TESTS PASSED\n");
|
||||
}
|
||||
printf("Tests run: %d\n", tests_run);
|
||||
|
||||
return result != 0;
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
#!/bin/env python
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
#
|
||||
# Usage: symbolstore.py <params> <dump_syms path> <symbol store path>
|
||||
# <debug info files or dirs>
|
||||
# Runs dump_syms on each debug info file specified on the command line,
|
||||
# then places the resulting symbol file in the proper directory
|
||||
# structure in the symbol store path. Accepts multiple files
|
||||
# on the command line, so can be called as part of a pipe using
|
||||
# find <dir> | xargs symbolstore.pl <dump_syms> <storepath>
|
||||
# But really, you might just want to pass it <dir>.
|
||||
#
|
||||
# Parameters accepted:
|
||||
# -c : Copy debug info files to the same directory structure
|
||||
# as sym files
|
||||
# -a "<archs>" : Run dump_syms -a <arch> for each space separated
|
||||
# cpu architecture in <archs> (only on OS X)
|
||||
# -s <srcdir> : Use <srcdir> as the top source directory to
|
||||
# generate relative filenames.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from optparse import OptionParser
|
||||
|
||||
# Utility functions
|
||||
|
||||
def GetCVSRevision(file):
|
||||
"""Given a full path to a file, look in CVS/Entries
|
||||
for the CVS revision number"""
|
||||
(path, filename) = os.path.split(file)
|
||||
entries = os.path.join(path, "CVS", "Entries")
|
||||
if not os.path.isfile(entries):
|
||||
return None
|
||||
f = open(entries, "r")
|
||||
for line in f:
|
||||
parts = line.split("/")
|
||||
if len(parts) > 1 and parts[1] == filename:
|
||||
return parts[2]
|
||||
print >> sys.stderr, "Failed to get CVS Revision for %s" % filename
|
||||
return None
|
||||
|
||||
def GetCVSRoot(file):
|
||||
"""Given a full path to a file, look in CVS/Root
|
||||
for the CVS Root"""
|
||||
(path, filename) = os.path.split(file)
|
||||
root = os.path.join(path, "CVS", "Root")
|
||||
if not os.path.isfile(root):
|
||||
return None
|
||||
f = open(root, "r")
|
||||
root_name = f.readline().strip()
|
||||
f.close()
|
||||
parts = root_name.split("@")
|
||||
if len(parts) > 1:
|
||||
# we don't want the extra colon
|
||||
return parts[1].replace(":","")
|
||||
print >> sys.stderr, "Failed to get CVS Root for %s" % filename
|
||||
return None
|
||||
|
||||
def GetVCSFilename(file, srcdir):
|
||||
"""Given a full path to a file, and the top source directory,
|
||||
look for version control information about this file, and return
|
||||
a specially formatted filename that contains the VCS type,
|
||||
VCS location, relative filename, and revision number, formatted like:
|
||||
vcs:vcs location:filename:revision
|
||||
For example:
|
||||
cvs:cvs.mozilla.org/cvsroot:mozilla/browser/app/nsBrowserApp.cpp:1.36"""
|
||||
(path, filename) = os.path.split(file)
|
||||
if path == '' or filename == '':
|
||||
return file
|
||||
|
||||
cvsdir = os.path.join(path, "CVS")
|
||||
if os.path.isdir(cvsdir):
|
||||
rev = GetCVSRevision(file)
|
||||
root = GetCVSRoot(file)
|
||||
if rev is not None and root is not None:
|
||||
if srcdir is not None:
|
||||
# strip the base path off
|
||||
# but we actually want the last dir in srcdir
|
||||
# also, we want forward slashes on win32 paths
|
||||
file = os.path.normpath(file)
|
||||
file = file.replace(srcdir, "", 1)
|
||||
(head, tail) = os.path.split(srcdir)
|
||||
if tail == "":
|
||||
tail = os.path.basename(head)
|
||||
file = tail + file
|
||||
file = file.replace("\\", "/")
|
||||
return "cvs:%s:%s:%s" % (root, file, rev)
|
||||
file = file.replace("\\", "/")
|
||||
return file
|
||||
|
||||
def GetPlatformSpecificDumper(**kwargs):
|
||||
"""This function simply returns a instance of a subclass of Dumper
|
||||
that is appropriate for the current platform."""
|
||||
return {'win32': Dumper_Win32,
|
||||
'cygwin': Dumper_Win32,
|
||||
'linux2': Dumper_Linux,
|
||||
'darwin': Dumper_Mac}[sys.platform](**kwargs)
|
||||
|
||||
class Dumper:
|
||||
"""This class can dump symbols from a file with debug info, and
|
||||
store the output in a directory structure that is valid for use as
|
||||
a Breakpad symbol server. Requires a path to a dump_syms binary--
|
||||
|dump_syms| and a directory to store symbols in--|symbol_path|.
|
||||
Optionally takes a list of processor architectures to process from
|
||||
each debug file--|archs|, the full path to the top source
|
||||
directory--|srcdir|, for generating relative source file names,
|
||||
and an option to copy debug info files alongside the dumped
|
||||
symbol files--|copy_debug|, mostly useful for creating a
|
||||
Microsoft Symbol Server from the resulting output.
|
||||
|
||||
You don't want to use this directly if you intend to call
|
||||
ProcessDir. Instead, call GetPlatformSpecificDumper to
|
||||
get an instance of a subclass."""
|
||||
def __init__(self, dump_syms, symbol_path,
|
||||
archs=None, srcdir=None, copy_debug=False, vcsinfo=False):
|
||||
self.dump_syms = dump_syms
|
||||
self.symbol_path = symbol_path
|
||||
if archs is None:
|
||||
# makes the loop logic simpler
|
||||
self.archs = ['']
|
||||
else:
|
||||
self.archs = ['-a %s' % a for a in archs.split()]
|
||||
if srcdir is not None:
|
||||
self.srcdir = os.path.normpath(srcdir)
|
||||
else:
|
||||
self.srcdir = None
|
||||
self.copy_debug = copy_debug
|
||||
self.vcsinfo = vcsinfo
|
||||
|
||||
# subclasses override this
|
||||
def ShouldProcess(self, file):
|
||||
return False
|
||||
|
||||
def RunFileCommand(self, file):
|
||||
"""Utility function, returns the output of file(1)"""
|
||||
try:
|
||||
# we use -L to read the targets of symlinks,
|
||||
# and -b to print just the content, not the filename
|
||||
return os.popen("file -Lb " + file).read()
|
||||
except:
|
||||
return ""
|
||||
|
||||
# This is a no-op except on Win32
|
||||
def FixFilenameCase(self, file):
|
||||
return file
|
||||
|
||||
def Process(self, file_or_dir):
|
||||
"Process a file or all the (valid) files in a directory."
|
||||
if os.path.isdir(file_or_dir):
|
||||
return self.ProcessDir(file_or_dir)
|
||||
elif os.path.isfile(file_or_dir):
|
||||
return self.ProcessFile(file_or_dir)
|
||||
# maybe it doesn't exist?
|
||||
return False
|
||||
|
||||
def ProcessDir(self, dir):
|
||||
"""Process all the valid files in this directory. Valid files
|
||||
are determined by calling ShouldProcess."""
|
||||
result = True
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for f in files:
|
||||
fullpath = os.path.join(root, f)
|
||||
if self.ShouldProcess(fullpath):
|
||||
if not self.ProcessFile(fullpath):
|
||||
result = False
|
||||
return result
|
||||
|
||||
def ProcessFile(self, file):
|
||||
"""Dump symbols from this file into a symbol file, stored
|
||||
in the proper directory structure in |symbol_path|."""
|
||||
result = False
|
||||
for arch in self.archs:
|
||||
try:
|
||||
cmd = os.popen("%s %s %s" % (self.dump_syms, arch, file), "r")
|
||||
module_line = cmd.next()
|
||||
if module_line.startswith("MODULE"):
|
||||
# MODULE os cpu guid debug_file
|
||||
(guid, debug_file) = (module_line.split())[3:5]
|
||||
# strip off .pdb extensions, and append .sym
|
||||
sym_file = re.sub("\.pdb$", "", debug_file) + ".sym"
|
||||
# we do want forward slashes here
|
||||
rel_path = os.path.join(debug_file,
|
||||
guid,
|
||||
sym_file).replace("\\", "/")
|
||||
full_path = os.path.normpath(os.path.join(self.symbol_path,
|
||||
rel_path))
|
||||
try:
|
||||
os.makedirs(os.path.dirname(full_path))
|
||||
except OSError: # already exists
|
||||
pass
|
||||
f = open(full_path, "w")
|
||||
f.write(module_line)
|
||||
# now process the rest of the output
|
||||
for line in cmd:
|
||||
if line.startswith("FILE"):
|
||||
# FILE index filename
|
||||
(x, index, filename) = line.split(None, 2)
|
||||
filename = self.FixFilenameCase(filename.rstrip())
|
||||
if self.vcsinfo:
|
||||
filename = GetVCSFilename(filename, self.srcdir)
|
||||
f.write("FILE %s %s\n" % (index, filename))
|
||||
else:
|
||||
# pass through all other lines unchanged
|
||||
f.write(line)
|
||||
f.close()
|
||||
cmd.close()
|
||||
# we output relative paths so callers can get a list of what
|
||||
# was generated
|
||||
print rel_path
|
||||
if self.copy_debug:
|
||||
rel_path = os.path.join(debug_file,
|
||||
guid,
|
||||
debug_file).replace("\\", "/")
|
||||
print rel_path
|
||||
full_path = os.path.normpath(os.path.join(self.symbol_path,
|
||||
rel_path))
|
||||
shutil.copyfile(file, full_path)
|
||||
result = True
|
||||
except StopIteration:
|
||||
pass
|
||||
except:
|
||||
print >> sys.stderr, "Unexpected error: ", sys.exc_info()[0]
|
||||
raise
|
||||
return result
|
||||
|
||||
# Platform-specific subclasses. For the most part, these just have
|
||||
# logic to determine what files to extract symbols from.
|
||||
|
||||
class Dumper_Win32(Dumper):
|
||||
def ShouldProcess(self, file):
|
||||
"""This function will allow processing of pdb files that have dll
|
||||
or exe files with the same base name next to them."""
|
||||
if file.endswith(".pdb"):
|
||||
(path,ext) = os.path.splitext(file)
|
||||
if os.path.isfile(path + ".exe") or os.path.isfile(path + ".dll"):
|
||||
return True
|
||||
return False
|
||||
|
||||
def FixFilenameCase(self, file):
|
||||
"""Recent versions of Visual C++ put filenames into
|
||||
PDB files as all lowercase. If the file exists
|
||||
on the local filesystem, fix it."""
|
||||
(path, filename) = os.path.split(file)
|
||||
if not os.path.isdir(path):
|
||||
return file
|
||||
lc_filename = filename.lower()
|
||||
for f in os.listdir(path):
|
||||
if f.lower() == lc_filename:
|
||||
return os.path.join(path, f)
|
||||
return file
|
||||
|
||||
class Dumper_Linux(Dumper):
|
||||
def ShouldProcess(self, file):
|
||||
"""This function will allow processing of files that are
|
||||
executable, or end with the .so extension, and additionally
|
||||
file(1) reports as being ELF files. It expects to find the file
|
||||
command in PATH."""
|
||||
if file.endswith(".so") or os.access(file, os.X_OK):
|
||||
return self.RunFileCommand(file).startswith("ELF")
|
||||
return False
|
||||
|
||||
class Dumper_Mac(Dumper):
|
||||
def ShouldProcess(self, file):
|
||||
"""This function will allow processing of files that are
|
||||
executable, or end with the .dylib extension, and additionally
|
||||
file(1) reports as being Mach-O files. It expects to find the file
|
||||
command in PATH."""
|
||||
if file.endswith(".dylib") or os.access(file, os.X_OK):
|
||||
return self.RunFileCommand(file).startswith("Mach-O")
|
||||
return False
|
||||
|
||||
# Entry point if called as a standalone program
|
||||
def main():
|
||||
parser = OptionParser(usage="usage: %prog [options] <dump_syms binary> <symbol store path> <debug info files>")
|
||||
parser.add_option("-c", "--copy",
|
||||
action="store_true", dest="copy_debug", default=False,
|
||||
help="Copy debug info files into the same directory structure as symbol files")
|
||||
parser.add_option("-a", "--archs",
|
||||
action="store", dest="archs",
|
||||
help="Run dump_syms -a <arch> for each space separated cpu architecture in ARCHS (only on OS X)")
|
||||
parser.add_option("-s", "--srcdir",
|
||||
action="store", dest="srcdir",
|
||||
help="Use SRCDIR to determine relative paths to source files")
|
||||
parser.add_option("-v", "--vcs-info",
|
||||
action="store_true", dest="vcsinfo",
|
||||
help="Try to retrieve VCS info for each FILE listed in the output")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if len(args) < 3:
|
||||
parser.error("not enough arguments")
|
||||
exit(1)
|
||||
|
||||
dumper = GetPlatformSpecificDumper(dump_syms=args[0],
|
||||
symbol_path=args[1],
|
||||
copy_debug=options.copy_debug,
|
||||
archs=options.archs,
|
||||
srcdir=options.srcdir,
|
||||
vcsinfo=options.vcsinfo)
|
||||
for arg in args[2:]:
|
||||
dumper.Process(arg)
|
||||
|
||||
# run main if run directly
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Ted Mielczarek <ted.mielczarek@gmail.com>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
#
|
||||
# This script expects the following environment variables to be set:
|
||||
# SYMBOL_SERVER_HOST : host to upload symbols to
|
||||
# SYMBOL_SERVER_USER : username on that host
|
||||
# SYMBOL_SERVER_PATH : path on that host to put symbols in
|
||||
#
|
||||
# And will use the following optional environment variable if set:
|
||||
# SYMBOL_SERVER_SSH_KEY : path to a ssh private key to use
|
||||
#
|
||||
set -e
|
||||
|
||||
: ${SYMBOL_SERVER_HOST?} ${SYMBOL_SERVER_USER?} ${SYMBOL_SERVER_PATH?} ${1?"You must specify a symbol archive to upload"}
|
||||
archive=`basename $1`
|
||||
echo "Transferring symbols... $1"
|
||||
scp -v ${SYMBOL_SERVER_SSH_KEY:+-i $SYMBOL_SERVER_SSH_KEY} $1 \
|
||||
${SYMBOL_SERVER_USER}@${SYMBOL_SERVER_HOST}:${SYMBOL_SERVER_PATH}/
|
||||
echo "Unpacking symbols on remote host..."
|
||||
ssh -2 ${SYMBOL_SERVER_SSH_KEY:+-i $SYMBOL_SERVER_SSH_KEY} \
|
||||
-l ${SYMBOL_SERVER_USER} ${SYMBOL_SERVER_HOST} \
|
||||
"set -e;
|
||||
umask 0022;
|
||||
cd ${SYMBOL_SERVER_PATH};
|
||||
unzip -o $archive;
|
||||
rm -v $archive;"
|
||||
echo "Symbol transfer completed"
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user