Backed out 2 changesets (bug 1330833) for windows 64 xpcshell failures a=backout
Backed out changeset 466565fa382a (bug 1330833) Backed out changeset 927194e7769d (bug 1330833) MozReview-Commit-ID: GB4KsH29xYC
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
#include <prproces.h>
|
||||
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
@@ -25,7 +24,6 @@
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsThreadManager.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
@@ -78,8 +76,6 @@
|
||||
#include "mozilla/PoisonIOInterposer.h"
|
||||
#include "mozilla/StartupTimeline.h"
|
||||
#include "mozilla/HangMonitor.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
#include "shared-libraries.h"
|
||||
@@ -100,8 +96,6 @@ namespace {
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::HangMonitor;
|
||||
using Telemetry::Common::AutoHashtable;
|
||||
using mozilla::dom::Promise;
|
||||
using mozilla::dom::AutoJSAPI;
|
||||
|
||||
// The maximum number of chrome hangs stacks that we're keeping.
|
||||
const size_t kMaxChromeStacksKept = 50;
|
||||
@@ -1660,197 +1654,8 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
class GetLoadedModulesResultRunnable final : public Runnable
|
||||
{
|
||||
nsMainThreadPtrHandle<Promise> mPromise;
|
||||
SharedLibraryInfo mRawModules;
|
||||
nsCOMPtr<nsIThread> mWorkerThread;
|
||||
|
||||
public:
|
||||
GetLoadedModulesResultRunnable(const nsMainThreadPtrHandle<Promise>& aPromise, const SharedLibraryInfo& rawModules)
|
||||
: mPromise(aPromise)
|
||||
, mRawModules(rawModules)
|
||||
, mWorkerThread(do_GetCurrentThread())
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mWorkerThread->Shutdown();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(mPromise->GlobalJSObject()))) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::RootedObject moduleArray(cx, JS_NewArrayObject(cx, 0));
|
||||
if (!moduleArray) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0, n = mRawModules.GetSize(); i != n; i++) {
|
||||
const SharedLibrary &info = mRawModules.GetEntry(i);
|
||||
|
||||
nsString basename = info.GetName();
|
||||
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
int32_t pos = basename.RFindChar('/');
|
||||
if (pos != kNotFound) {
|
||||
basename.Cut(0, pos + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsString debug_basename = info.GetDebugName();
|
||||
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
pos = debug_basename.RFindChar('/');
|
||||
if (pos != kNotFound) {
|
||||
debug_basename.Cut(0, pos + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
JS::RootedObject moduleObj(cx, JS_NewPlainObject(cx));
|
||||
if (!moduleObj) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Module name.
|
||||
JS::RootedString moduleName(cx, JS_NewUCStringCopyZ(cx, basename.get()));
|
||||
if (!moduleName || !JS_DefineProperty(cx, moduleObj, "name", moduleName, JSPROP_ENUMERATE)) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Module debug name.
|
||||
JS::RootedValue moduleDebugName(cx);
|
||||
|
||||
if (!debug_basename.IsEmpty()) {
|
||||
JS::RootedString str_moduleDebugName(cx, JS_NewUCStringCopyZ(cx, debug_basename.get()));
|
||||
if (!str_moduleDebugName) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
moduleDebugName.setString(str_moduleDebugName);
|
||||
}
|
||||
else {
|
||||
moduleDebugName.setNull();
|
||||
}
|
||||
|
||||
if (!JS_DefineProperty(cx, moduleObj, "debugName", moduleDebugName, JSPROP_ENUMERATE)) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Module Breakpad identifier.
|
||||
JS::RootedValue id(cx);
|
||||
|
||||
if (!info.GetBreakpadId().empty()) {
|
||||
JS::RootedString str_id(cx, JS_NewStringCopyZ(cx, info.GetBreakpadId().c_str()));
|
||||
if (!str_id) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
id.setString(str_id);
|
||||
} else {
|
||||
id.setNull();
|
||||
}
|
||||
|
||||
if (!JS_DefineProperty(cx, moduleObj, "debugID", id, JSPROP_ENUMERATE)) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Module version.
|
||||
JS::RootedValue version(cx);
|
||||
|
||||
if (!info.GetVersion().empty()) {
|
||||
JS::RootedString v(cx, JS_NewStringCopyZ(cx, info.GetVersion().c_str()));
|
||||
if (!v) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
version.setString(v);
|
||||
} else {
|
||||
version.setNull();
|
||||
}
|
||||
|
||||
if (!JS_DefineProperty(cx, moduleObj, "version", version, JSPROP_ENUMERATE)) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!JS_DefineElement(cx, moduleArray, i, moduleObj, JSPROP_ENUMERATE)) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(moduleArray);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class GetLoadedModulesRunnable final : public Runnable
|
||||
{
|
||||
nsMainThreadPtrHandle<Promise> mPromise;
|
||||
|
||||
public:
|
||||
explicit GetLoadedModulesRunnable(const nsMainThreadPtrHandle<Promise>& aPromise)
|
||||
: mPromise(aPromise)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> resultRunnable = new GetLoadedModulesResultRunnable(mPromise, SharedLibraryInfo::GetInfoForSelf());
|
||||
return NS_DispatchToMainThread(resultRunnable);
|
||||
}
|
||||
};
|
||||
#endif // MOZ_GECKO_PROFILER
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelemetryImpl::GetLoadedModules(JSContext *cx, nsISupports** aPromise)
|
||||
{
|
||||
nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx));
|
||||
if (NS_WARN_IF(!global)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ErrorResult result;
|
||||
RefPtr<Promise> promise = Promise::Create(global, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
nsCOMPtr<nsIThreadManager> tm = do_GetService(NS_THREADMANAGER_CONTRACTID);
|
||||
nsCOMPtr<nsIThread> getModulesThread;
|
||||
nsresult rv = tm->NewThread(0, 0, getter_AddRefs(getModulesThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<Promise> mainThreadPromise(new nsMainThreadPtrHolder<Promise>(promise));
|
||||
nsCOMPtr<nsIRunnable> runnable = new GetLoadedModulesRunnable(mainThreadPromise);
|
||||
promise.forget(aPromise);
|
||||
|
||||
return getModulesThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
|
||||
#else // MOZ_GECKO_PROFILER
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif // MOZ_GECKO_PROFILER
|
||||
}
|
||||
|
||||
static bool
|
||||
IsValidBreakpadId(const std::string &breakpadId)
|
||||
{
|
||||
IsValidBreakpadId(const std::string &breakpadId) {
|
||||
if (breakpadId.size() < 33) {
|
||||
return false;
|
||||
}
|
||||
@@ -3224,14 +3029,15 @@ GetStackAndModules(const std::vector<uintptr_t>& aPCs)
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
for (unsigned i = 0, n = rawModules.GetSize(); i != n; ++i) {
|
||||
const SharedLibrary &info = rawModules.GetEntry(i);
|
||||
std::string basename = info.GetNativeDebugName();
|
||||
const std::string &name = info.GetName();
|
||||
std::string basename = name;
|
||||
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||
// We want to use just the basename as the libname, but the
|
||||
// current profiler addon needs the full path name, so we compute the
|
||||
// basename in here.
|
||||
size_t pos = basename.rfind('/');
|
||||
size_t pos = name.rfind('/');
|
||||
if (pos != std::string::npos) {
|
||||
basename = basename.substr(pos + 1);
|
||||
basename = name.substr(pos + 1);
|
||||
}
|
||||
#endif
|
||||
mozilla::Telemetry::ProcessedStack::Module module = {
|
||||
|
||||
@@ -84,8 +84,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySend",
|
||||
"resource://gre/modules/TelemetrySend.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryReportingPolicy",
|
||||
"resource://gre/modules/TelemetryReportingPolicy.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryModules",
|
||||
"resource://gre/modules/TelemetryModules.jsm");
|
||||
|
||||
/**
|
||||
* Setup Telemetry logging. This function also gets called when loggin related
|
||||
@@ -752,9 +750,6 @@ var Impl = {
|
||||
// in the future.
|
||||
TelemetryStorage.removeFHRDatabase();
|
||||
|
||||
// Report the modules loaded in the Firefox process.
|
||||
TelemetryModules.start();
|
||||
|
||||
this._delayedInitTaskDeferred.resolve();
|
||||
} catch (e) {
|
||||
this._delayedInitTaskDeferred.reject(e);
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
"resource://gre/modules/Preferences.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Log",
|
||||
"resource://gre/modules/Log.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
|
||||
"resource://gre/modules/TelemetryController.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gUpdateTimerManager",
|
||||
"@mozilla.org/updates/timer-manager;1", "nsIUpdateTimerManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
|
||||
"@mozilla.org/base/telemetry;1", "nsITelemetry");
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"TelemetryModules",
|
||||
];
|
||||
|
||||
const LOGGER_NAME = "Toolkit.Telemetry";
|
||||
const LOGGER_PREFIX = "TelemetryModules::";
|
||||
|
||||
// The default is 1 week.
|
||||
const MODULES_PING_INTERVAL_SECONDS = 7 * 24 * 60 * 60;
|
||||
const MODULES_PING_INTERVAL_PREFERENCE = "toolkit.telemetry.modulesPing.interval";
|
||||
|
||||
const MAX_MODULES_NUM = 512;
|
||||
const MAX_NAME_LENGTH = 64;
|
||||
const TRUNCATION_DELIMITER = "\u2026";
|
||||
|
||||
this.TelemetryModules = Object.freeze({
|
||||
_log: Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX),
|
||||
|
||||
start() {
|
||||
// The list of loaded modules is obtainable only when the profiler is enabled.
|
||||
// If it isn't, we don't want to send the ping at all.
|
||||
if (!AppConstants.MOZ_GECKO_PROFILER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use nsIUpdateTimerManager for a long-duration timer that survives across sessions.
|
||||
gUpdateTimerManager.registerTimer(
|
||||
"telemetry_modules_ping",
|
||||
this,
|
||||
Preferences.get(MODULES_PING_INTERVAL_PREFERENCE, MODULES_PING_INTERVAL_SECONDS)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the 'telemetry_modules_ping' timer fires.
|
||||
*/
|
||||
notify() {
|
||||
try {
|
||||
Telemetry.getLoadedModules().then(
|
||||
modules => {
|
||||
modules = modules.filter(module => module.name.length > 0);
|
||||
|
||||
// Cut the list of modules to MAX_MODULES_NUM entries.
|
||||
if (modules.length > MAX_MODULES_NUM) {
|
||||
modules = modules.slice(0, MAX_MODULES_NUM);
|
||||
}
|
||||
|
||||
// Cut the file names of the modules to MAX_NAME_LENGTH characters.
|
||||
for (let module of modules) {
|
||||
if (module.name.length > MAX_NAME_LENGTH) {
|
||||
module.name = module.name.substr(0, MAX_NAME_LENGTH - 1) + TRUNCATION_DELIMITER;
|
||||
}
|
||||
|
||||
if (module.debugName !== null && module.debugName.length > MAX_NAME_LENGTH) {
|
||||
module.debugName = module.debugName.substr(0, MAX_NAME_LENGTH - 1) + TRUNCATION_DELIMITER;
|
||||
}
|
||||
}
|
||||
|
||||
TelemetryController.submitExternalPing("modules",
|
||||
{
|
||||
version: 1,
|
||||
modules,
|
||||
},
|
||||
{
|
||||
addClientId: true,
|
||||
addEnvironment: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
err => this._log.error("notify - promise failed", ex)
|
||||
);
|
||||
} catch (ex) {
|
||||
this._log.error("notify - caught exception", ex);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
"modules" ping
|
||||
============
|
||||
|
||||
This ping is sent once a week and includes the modules loaded in the Firefox process.
|
||||
|
||||
The client ID and environment is submitted with this ping.
|
||||
|
||||
Structure:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
{
|
||||
type: "modules",
|
||||
... common ping data
|
||||
clientId: <UUID>,
|
||||
environment: { ... },
|
||||
payload: {
|
||||
version: 1,
|
||||
modules: [
|
||||
{
|
||||
name: <string>, // Name of the module file (e.g. xul.dll)
|
||||
version: <string>, // Version of the module
|
||||
debugID: <string>, // ID of the debug information file
|
||||
debugName: <string>, // Name of the debug information file
|
||||
},
|
||||
...
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
Notes
|
||||
~~~~~
|
||||
|
||||
The version information is only available on Windows, it is null on other platforms.
|
||||
|
||||
The debug name is the name of the PDB on Windows (which isn't always the same as the module name modulo the extension, e.g. the PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb) and is the same as the module name on other platforms.
|
||||
|
||||
The debug ID is platform-dependent. It is compatible with the Breakpad ID used on Socorro.
|
||||
|
||||
Sometimes the debug name and debug ID are missing for Windows modules (often with malware). In this case, they will be "null".
|
||||
|
||||
The length of the modules array is limited to 512 entries.
|
||||
|
||||
The name and debug name are length limited, with a maximum of 64 characters.
|
||||
@@ -118,10 +118,6 @@ The following prefs are for testing purpose only.
|
||||
|
||||
Timeout until we decide whether a user is idle or not (seconds).
|
||||
|
||||
``toolkit.telemetry.modulesPing.interval``
|
||||
|
||||
Interval between "modules" ping transmissions.
|
||||
|
||||
``toolkit.telemetry.send.overrideOfficialCheck``
|
||||
|
||||
If true, allows sending pings on unofficial builds. Requires a restart.
|
||||
|
||||
@@ -30,8 +30,6 @@ if CONFIG['GNU_CXX']:
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
DIRS += ['tests/gtest']
|
||||
|
||||
TEST_DIRS += ['tests']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
|
||||
|
||||
@@ -74,7 +72,6 @@ EXTRA_JS_MODULES += [
|
||||
'TelemetryController.jsm',
|
||||
'TelemetryEnvironment.jsm',
|
||||
'TelemetryLog.jsm',
|
||||
'TelemetryModules.jsm',
|
||||
'TelemetryReportingPolicy.jsm',
|
||||
'TelemetrySend.jsm',
|
||||
'TelemetrySession.jsm',
|
||||
|
||||
@@ -180,25 +180,6 @@ interface nsITelemetry : nsISupports
|
||||
[implicit_jscontext]
|
||||
jsval snapshotCapturedStacks([optional] in boolean clear);
|
||||
|
||||
/*
|
||||
* Returns an array of the modules loaded in the process. The data has the following structure:
|
||||
*
|
||||
* [
|
||||
* {
|
||||
* "name": <string>, // Name of the module file (e.g. xul.dll)
|
||||
* "version": <string>, // Version of the module
|
||||
* "debugName": <string>, // ID of the debug information file
|
||||
* "debugID": <string>, // Name of the debug information file
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
*
|
||||
* @return An array of modules.
|
||||
* @throws NS_ERROR_FAILURE on failure.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
nsISupports getLoadedModules();
|
||||
|
||||
/*
|
||||
* An array of thread hang stats,
|
||||
* [<thread>, <thread>, ...]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
void nothing()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIST_INSTALL = False
|
||||
|
||||
SOURCES += [
|
||||
'modules-test.cpp',
|
||||
]
|
||||
|
||||
SharedLibrary('modules-test')
|
||||
|
||||
if CONFIG['COMPILE_ENVIRONMENT']:
|
||||
shared_library = '!%smodules-test%s' % (CONFIG['DLL_PREFIX'], CONFIG['DLL_SUFFIX'])
|
||||
TEST_HARNESS_FILES.xpcshell.toolkit.components.telemetry.tests.unit += [shared_library]
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,176 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/TelemetryModules.jsm");
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const MAX_NAME_LENGTH = 64;
|
||||
|
||||
const libModules = ctypes.libraryName("modules-test");
|
||||
const libUnicode = ctypes.libraryName("modμles-test");
|
||||
const libLongName = "lorem_ipsum_dolor_sit_amet_consectetur_adipiscing_elit_Fusce_sit_amet_tellus_non_magna_euismod_vestibulum_Vivamus_turpis_duis.dll"
|
||||
const libUnicodePDB = "testUnicodePDB.dll";
|
||||
const libNoPDB = "testNoPDB.dll";
|
||||
const libxul = OS.Path.basename(OS.Constants.Path.libxul);
|
||||
|
||||
const libModulesFile = do_get_file(libModules).path;
|
||||
const libUnicodeFile = OS.Path.join(OS.Path.dirname(libModulesFile), libUnicode);
|
||||
const libLongNameFile = OS.Path.join(OS.Path.dirname(libModulesFile), libLongName);
|
||||
const libUnicodePDBFile = do_get_file(libUnicodePDB).path;
|
||||
const libNoPDBFile = do_get_file(libNoPDB).path;
|
||||
|
||||
let libModulesHandle, libUnicodeHandle, libLongNameHandle, libUnicodePDBHandle, libNoPDBHandle;
|
||||
|
||||
let expectedLibs;
|
||||
if (AppConstants.platform === "win") {
|
||||
const version = AppConstants.MOZ_APP_VERSION.substring(0, AppConstants.MOZ_APP_VERSION.indexOf(".") + 2);
|
||||
|
||||
expectedLibs = [
|
||||
{
|
||||
name: libxul,
|
||||
debugName: libxul.replace(".dll", ".pdb"),
|
||||
version,
|
||||
},
|
||||
{
|
||||
name: libModules,
|
||||
debugName: libModules.replace(".dll", ".pdb"),
|
||||
version,
|
||||
},
|
||||
{
|
||||
name: libUnicode,
|
||||
debugName: libModules.replace(".dll", ".pdb"),
|
||||
version,
|
||||
},
|
||||
{
|
||||
name: libLongName.substring(0, MAX_NAME_LENGTH - 1) + "…",
|
||||
debugName: libModules.replace(".dll", ".pdb"),
|
||||
version,
|
||||
},
|
||||
{
|
||||
name: libUnicodePDB,
|
||||
debugName: "libmodμles.pdb",
|
||||
version: null,
|
||||
},
|
||||
{
|
||||
name: libNoPDB,
|
||||
debugName: null,
|
||||
version: null,
|
||||
},
|
||||
];
|
||||
} else if (AppConstants.platform === "android") {
|
||||
// Listing shared libraries doesn't work in Android xpcshell tests.
|
||||
// https://hg.mozilla.org/mozilla-central/file/0eef1d5a39366059677c6d7944cfe8a97265a011/tools/profiler/core/shared-libraries-linux.cc#l95
|
||||
expectedLibs = [];
|
||||
} else {
|
||||
expectedLibs = [
|
||||
{
|
||||
name: libxul,
|
||||
debugName: libxul,
|
||||
version: null,
|
||||
},
|
||||
{
|
||||
name: libModules,
|
||||
debugName: libModules,
|
||||
version: null,
|
||||
},
|
||||
{
|
||||
name: libUnicode,
|
||||
debugName: libUnicode,
|
||||
version: null,
|
||||
},
|
||||
{
|
||||
name: libLongName.substring(0, MAX_NAME_LENGTH - 1) + "…",
|
||||
debugName: libLongName.substring(0, MAX_NAME_LENGTH - 1) + "…",
|
||||
version: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
do_get_profile();
|
||||
|
||||
yield OS.File.copy(libModulesFile, libUnicodeFile);
|
||||
yield OS.File.copy(libModulesFile, libLongName);
|
||||
|
||||
if (AppConstants.platform !== "android") {
|
||||
libModulesHandle = ctypes.open(libModulesFile);
|
||||
libUnicodeHandle = ctypes.open(libUnicodeFile);
|
||||
libLongNameHandle = ctypes.open(libLongNameFile);
|
||||
if (AppConstants.platform === "win") {
|
||||
libUnicodePDBHandle = ctypes.open(libUnicodePDBFile);
|
||||
libNoPDBHandle = ctypes.open(libNoPDBFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Force the timer to fire (using a small interval).
|
||||
Cc["@mozilla.org/updates/timer-manager;1"].getService(Ci.nsIObserver).observe(null, "utm-test-init", "");
|
||||
Preferences.set("toolkit.telemetry.modulesPing.interval", 0);
|
||||
Preferences.set("app.update.url", "http:/localhost");
|
||||
|
||||
// Start the local ping server and setup Telemetry to use it during the tests.
|
||||
PingServer.start();
|
||||
Preferences.set("toolkit.telemetry.server", "http://localhost:" + PingServer.port);
|
||||
});
|
||||
|
||||
do_register_cleanup(function() {
|
||||
if (libModulesHandle) {
|
||||
libModulesHandle.close();
|
||||
}
|
||||
if (libUnicodeHandle) {
|
||||
libUnicodeHandle.close();
|
||||
}
|
||||
if (libLongNameHandle) {
|
||||
libLongNameHandle.close();
|
||||
}
|
||||
if (libUnicodePDBHandle) {
|
||||
libUnicodePDBHandle.close();
|
||||
}
|
||||
if (libNoPDBHandle) {
|
||||
libNoPDBHandle.close();
|
||||
}
|
||||
|
||||
return OS.File.remove(libUnicodeFile)
|
||||
.then(() => OS.File.remove(libLongNameFile))
|
||||
.then(() => PingServer.stop());
|
||||
});
|
||||
|
||||
add_task({
|
||||
skip_if: () => !AppConstants.MOZ_GECKO_PROFILER,
|
||||
}, function* test_send_ping() {
|
||||
yield TelemetryController.testSetup();
|
||||
|
||||
let found = yield PingServer.promiseNextPing();
|
||||
Assert.ok(!!found, "Telemetry ping submitted.");
|
||||
Assert.strictEqual(found.type, "modules", "Ping type is 'modules'");
|
||||
Assert.ok(found.environment, "'modules' ping has an environment.");
|
||||
Assert.ok(!!found.clientId, "'modules' ping has a client ID.");
|
||||
Assert.ok(!!found.payload.modules, "Telemetry ping payload contains the 'modules' array.");
|
||||
|
||||
for (let lib of expectedLibs) {
|
||||
let test_lib = found.payload.modules.find(module => module.name === lib.name);
|
||||
|
||||
Assert.ok(!!test_lib, "There is a '" + lib.name + "' module.");
|
||||
|
||||
if (lib.version !== null) {
|
||||
Assert.ok(test_lib.version.startsWith(lib.version), "The version of the " + lib.name + " module (" + test_lib.version + ") is correct (it starts with '" + lib.version + "').");
|
||||
} else {
|
||||
Assert.strictEqual(test_lib.version, null, "The version of the " + lib.name + " module is null.");
|
||||
}
|
||||
|
||||
Assert.strictEqual(test_lib.debugName, lib.debugName, "The " + lib.name + " module has the correct debug name.");
|
||||
|
||||
if (lib.debugName === null) {
|
||||
Assert.strictEqual(test_lib.debugID, null, "The " + lib.name + " module doesn't have a debug ID.");
|
||||
} else {
|
||||
Assert.greater(test_lib.debugID.length, 0, "The " + lib.name + " module has a debug ID.");
|
||||
}
|
||||
}
|
||||
|
||||
let test_lib = found.payload.modules.find(module => module.name === libLongName);
|
||||
Assert.ok(!test_lib, "There isn't a '" + libLongName + "' module.");
|
||||
});
|
||||
@@ -14,8 +14,6 @@ support-files =
|
||||
system.xpi
|
||||
restartless.xpi
|
||||
theme.xpi
|
||||
testUnicodePDB.dll
|
||||
testNoPDB.dll
|
||||
!/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
|
||||
generated-files =
|
||||
dictionary.xpi
|
||||
@@ -65,6 +63,5 @@ tags = addons
|
||||
skip-if = toolkit == 'android'
|
||||
[test_TelemetryCaptureStack.js]
|
||||
[test_TelemetryEvents.js]
|
||||
[test_TelemetryModules.js]
|
||||
[test_PingSender.js]
|
||||
skip-if = (os == "android") || (os == "linux" && bits == 32)
|
||||
|
||||
@@ -638,7 +638,7 @@ void EHAddrSpace::Update() {
|
||||
// itself.
|
||||
continue;
|
||||
EHTable tab(reinterpret_cast<const void *>(lib.GetStart()),
|
||||
lib.GetEnd() - lib.GetStart(), lib.GetNativeDebugName());
|
||||
lib.GetEnd() - lib.GetStart(), lib.GetName());
|
||||
if (tab.isValid())
|
||||
tables.push_back(tab);
|
||||
}
|
||||
|
||||
@@ -888,9 +888,34 @@ AddSharedLibraryInfoToStream(std::ostream& aStream, const SharedLibrary& aLib)
|
||||
aStream << "\"start\":" << aLib.GetStart();
|
||||
aStream << ",\"end\":" << aLib.GetEnd();
|
||||
aStream << ",\"offset\":" << aLib.GetOffset();
|
||||
aStream << ",\"name\":\"" << aLib.GetNativeDebugName() << "\"";
|
||||
aStream << ",\"name\":\"" << aLib.GetName() << "\"";
|
||||
const std::string& breakpadId = aLib.GetBreakpadId();
|
||||
aStream << ",\"breakpadId\":\"" << breakpadId << "\"";
|
||||
|
||||
#ifdef XP_WIN
|
||||
// FIXME: remove this XP_WIN code when the profiler plugin has switched to
|
||||
// using breakpadId.
|
||||
std::string pdbSignature = breakpadId.substr(0, 32);
|
||||
std::string pdbAgeStr = breakpadId.substr(32, breakpadId.size() - 1);
|
||||
|
||||
std::stringstream stream;
|
||||
stream << pdbAgeStr;
|
||||
|
||||
unsigned pdbAge;
|
||||
stream << std::hex;
|
||||
stream >> pdbAge;
|
||||
|
||||
#ifdef DEBUG
|
||||
std::ostringstream oStream;
|
||||
oStream << pdbSignature << std::hex << std::uppercase << pdbAge;
|
||||
MOZ_ASSERT(breakpadId == oStream.str());
|
||||
#endif
|
||||
|
||||
aStream << ",\"pdbSignature\":\"" << pdbSignature << "\"";
|
||||
aStream << ",\"pdbAge\":" << pdbAge;
|
||||
aStream << ",\"pdbName\":\"" << aLib.GetName() << "\"";
|
||||
#endif
|
||||
|
||||
aStream << "}";
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <fstream>
|
||||
#include "platform.h"
|
||||
#include "shared-libraries.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
#include "common/linux/file_id.h"
|
||||
#include <algorithm>
|
||||
@@ -82,11 +80,7 @@ dl_iterate_callback(struct dl_phdr_info *dl_info, size_t size, void *data)
|
||||
libEnd = end;
|
||||
}
|
||||
const char *name = dl_info->dlpi_name;
|
||||
|
||||
nsAutoString nameStr;
|
||||
mozilla::Unused << NS_WARN_IF(NS_FAILED(NS_CopyNativeToUnicode(nsDependentCString(name), nameStr)));
|
||||
|
||||
SharedLibrary shlib(libStart, libEnd, 0, getId(name), nameStr, nameStr, "");
|
||||
SharedLibrary shlib(libStart, libEnd, 0, getId(name), name);
|
||||
info.AddSharedLibrary(shlib);
|
||||
|
||||
return 0;
|
||||
@@ -152,11 +146,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsAutoString nameStr;
|
||||
mozilla::Unused << NS_WARN_IF(NS_FAILED(NS_CopyNativeToUnicode(nsDependentCString(name), nameStr)));
|
||||
|
||||
SharedLibrary shlib(start, end, offset, getId(name), nameStr, nameStr, "");
|
||||
SharedLibrary shlib(start, end, offset, getId(name), name);
|
||||
info.AddSharedLibrary(shlib);
|
||||
if (count > 10000) {
|
||||
LOG("Get maps failed");
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
#include "shared-libraries.h"
|
||||
|
||||
@@ -72,11 +70,8 @@ void addSharedLibrary(const platform_mach_header* header, char *name, SharedLibr
|
||||
uuid << '0';
|
||||
}
|
||||
|
||||
nsAutoString nameStr;
|
||||
mozilla::Unused << NS_WARN_IF(NS_FAILED(NS_CopyNativeToUnicode(nsDependentCString(name), nameStr)));
|
||||
|
||||
info.AddSharedLibrary(SharedLibrary(start, start + size, 0, uuid.str(),
|
||||
nameStr, nameStr, ""));
|
||||
name));
|
||||
}
|
||||
|
||||
// Use dyld to inspect the macho image information. We can build the SharedLibraryEntry structure
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <dbghelp.h>
|
||||
#include <sstream>
|
||||
#include <psapi.h>
|
||||
|
||||
#include "shared-libraries.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
#define CV_SIGNATURE 0x53445352 // 'SDSR'
|
||||
|
||||
@@ -21,7 +18,6 @@ struct CodeViewRecord70
|
||||
uint32_t signature;
|
||||
GUID pdbSignature;
|
||||
uint32_t pdbAge;
|
||||
// A UTF-8 string, according to https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/PDB/dbi/locator.cpp#L785
|
||||
char pdbFileName[1];
|
||||
};
|
||||
|
||||
@@ -69,7 +65,13 @@ static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge, char*
|
||||
|
||||
// The PDB file name could be different from module filename, so report both
|
||||
// e.g. The PDB for C:\Windows\SysWOW64\ntdll.dll is wntdll.pdb
|
||||
*aPdbName = debugInfo->pdbFileName;
|
||||
char * leafName = strrchr(debugInfo->pdbFileName, '\\');
|
||||
if (leafName) {
|
||||
// Only report the file portion of the path
|
||||
*aPdbName = leafName + 1;
|
||||
} else {
|
||||
*aPdbName = debugInfo->pdbFileName;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -79,121 +81,55 @@ static bool IsDashOrBraces(char c)
|
||||
return c == '-' || c == '{' || c == '}';
|
||||
}
|
||||
|
||||
std::string GetVersion(WCHAR* dllPath)
|
||||
{
|
||||
DWORD infoSize = GetFileVersionInfoSizeW(dllPath, nullptr);
|
||||
if (infoSize == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<unsigned char[]> infoData = mozilla::MakeUnique<unsigned char[]>(infoSize);
|
||||
if (!GetFileVersionInfoW(dllPath, 0, infoSize, infoData.get())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO* vInfo;
|
||||
UINT vInfoLen;
|
||||
if (!VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)) {
|
||||
return "";
|
||||
}
|
||||
if (!vInfo) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << (vInfo->dwFileVersionMS >> 16) << "."
|
||||
<< (vInfo->dwFileVersionMS & 0xFFFF) << "."
|
||||
<< (vInfo->dwFileVersionLS >> 16) << "."
|
||||
<< (vInfo->dwFileVersionLS & 0xFFFF);
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
|
||||
{
|
||||
SharedLibraryInfo sharedLibraryInfo;
|
||||
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
mozilla::UniquePtr<HMODULE[]> hMods;
|
||||
size_t modulesNum = 0;
|
||||
if (hProcess != NULL) {
|
||||
DWORD modulesSize;
|
||||
if (!EnumProcessModules(hProcess, nullptr, 0, &modulesSize)) {
|
||||
return sharedLibraryInfo;
|
||||
}
|
||||
modulesNum = modulesSize / sizeof(HMODULE);
|
||||
hMods = mozilla::MakeUnique<HMODULE[]>(modulesNum);
|
||||
if (!EnumProcessModules(hProcess, hMods.get(), modulesNum * sizeof(HMODULE), &modulesSize)) {
|
||||
return sharedLibraryInfo;
|
||||
}
|
||||
}
|
||||
nsAutoHandle snap(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()));
|
||||
|
||||
for (unsigned int i = 0; i <= modulesNum; i++) {
|
||||
nsID pdbSig;
|
||||
uint32_t pdbAge;
|
||||
nsAutoString pdbNameStr;
|
||||
char *pdbName = NULL;
|
||||
std::string breakpadId;
|
||||
WCHAR modulePath[MAX_PATH + 1];
|
||||
MODULEENTRY32 module = {0};
|
||||
module.dwSize = sizeof(MODULEENTRY32);
|
||||
if (Module32First(snap, &module)) {
|
||||
do {
|
||||
nsID pdbSig;
|
||||
uint32_t pdbAge;
|
||||
char *pdbName = NULL;
|
||||
|
||||
if (!GetModuleFileNameEx(hProcess, hMods[i], modulePath, sizeof(modulePath) / sizeof(WCHAR))) {
|
||||
continue;
|
||||
}
|
||||
// Load the module again to make sure that its handle will remain remain
|
||||
// valid as we attempt to read the PDB information from it. We load the
|
||||
// DLL as a datafile so that if the module actually gets unloaded between
|
||||
// the call to Module32Next and the following LoadLibraryEx, we don't end
|
||||
// up running the now newly loaded module's DllMain function. If the
|
||||
// module is already loaded, LoadLibraryEx just increments its refcount.
|
||||
//
|
||||
// Note that because of the race condition above, merely loading the DLL
|
||||
// again is not safe enough, therefore we also need to make sure that we
|
||||
// can read the memory mapped at the base address before we can safely
|
||||
// proceed to actually access those pages.
|
||||
HMODULE handleLock = LoadLibraryEx(module.szExePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
MEMORY_BASIC_INFORMATION vmemInfo = {0};
|
||||
if (handleLock &&
|
||||
sizeof(vmemInfo) == VirtualQuery(module.modBaseAddr, &vmemInfo, sizeof(vmemInfo)) &&
|
||||
vmemInfo.State == MEM_COMMIT &&
|
||||
GetPdbInfo((uintptr_t)module.modBaseAddr, pdbSig, pdbAge, &pdbName)) {
|
||||
std::ostringstream stream;
|
||||
stream << pdbSig.ToString() << std::hex << pdbAge;
|
||||
std::string breakpadId = stream.str();
|
||||
std::string::iterator end =
|
||||
std::remove_if(breakpadId.begin(), breakpadId.end(), IsDashOrBraces);
|
||||
breakpadId.erase(end, breakpadId.end());
|
||||
std::transform(breakpadId.begin(), breakpadId.end(),
|
||||
breakpadId.begin(), toupper);
|
||||
|
||||
MODULEINFO module = {0};
|
||||
if (!GetModuleInformation(hProcess, hMods[i], &module, sizeof(MODULEINFO))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load the module again to make sure that its handle will remain remain
|
||||
// valid as we attempt to read the PDB information from it. We load the
|
||||
// DLL as a datafile so that if the module actually gets unloaded between
|
||||
// the call to EnumProcessModules and the following LoadLibraryEx, we don't
|
||||
// end up running the now newly loaded module's DllMain function. If the
|
||||
// module is already loaded, LoadLibraryEx just increments its refcount.
|
||||
//
|
||||
// Note that because of the race condition above, merely loading the DLL
|
||||
// again is not safe enough, therefore we also need to make sure that we
|
||||
// can read the memory mapped at the base address before we can safely
|
||||
// proceed to actually access those pages.
|
||||
HMODULE handleLock = LoadLibraryEx(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
MEMORY_BASIC_INFORMATION vmemInfo = { 0 };
|
||||
if (handleLock &&
|
||||
sizeof(vmemInfo) == VirtualQuery(module.lpBaseOfDll, &vmemInfo, sizeof(vmemInfo)) &&
|
||||
vmemInfo.State == MEM_COMMIT &&
|
||||
GetPdbInfo((uintptr_t)module.lpBaseOfDll, pdbSig, pdbAge, &pdbName)) {
|
||||
std::ostringstream stream;
|
||||
stream << pdbSig.ToString() << std::hex << pdbAge;
|
||||
breakpadId = stream.str();
|
||||
std::string::iterator end =
|
||||
std::remove_if(breakpadId.begin(), breakpadId.end(), IsDashOrBraces);
|
||||
breakpadId.erase(end, breakpadId.end());
|
||||
std::transform(breakpadId.begin(), breakpadId.end(),
|
||||
breakpadId.begin(), toupper);
|
||||
|
||||
pdbNameStr = NS_ConvertUTF8toUTF16(pdbName);
|
||||
int32_t pos = pdbNameStr.RFindChar('\\');
|
||||
if (pos != kNotFound) {
|
||||
pdbNameStr.Cut(0, pos + 1);
|
||||
SharedLibrary shlib((uintptr_t)module.modBaseAddr,
|
||||
(uintptr_t)module.modBaseAddr+module.modBaseSize,
|
||||
0, // DLLs are always mapped at offset 0 on Windows
|
||||
breakpadId,
|
||||
pdbName);
|
||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString moduleName(modulePath);
|
||||
int32_t pos = moduleName.RFindChar('\\');
|
||||
if (pos != kNotFound) {
|
||||
moduleName.Cut(0, pos + 1);
|
||||
}
|
||||
|
||||
SharedLibrary shlib((uintptr_t)module.lpBaseOfDll,
|
||||
(uintptr_t)module.lpBaseOfDll + module.SizeOfImage,
|
||||
0, // DLLs are always mapped at offset 0 on Windows
|
||||
breakpadId,
|
||||
moduleName,
|
||||
pdbNameStr,
|
||||
GetVersion(modulePath));
|
||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||
|
||||
FreeLibrary(handleLock); // ok to free null handles
|
||||
FreeLibrary(handleLock); // ok to free null handles
|
||||
} while (Module32Next(snap, &module));
|
||||
}
|
||||
|
||||
return sharedLibraryInfo;
|
||||
|
||||
@@ -32,8 +32,6 @@ read_procmaps(lul::LUL* aLUL)
|
||||
for (size_t i = 0; i < info.GetSize(); i++) {
|
||||
const SharedLibrary& lib = info.GetEntry(i);
|
||||
|
||||
std::string nativeName = lib.GetNativeDebugName();
|
||||
|
||||
# if defined(USE_FAULTY_LIB)
|
||||
// We're using faulty.lib. Use a special-case object mapper.
|
||||
AutoObjectMapperFaultyLib mapper(aLUL->mLog);
|
||||
@@ -46,11 +44,11 @@ read_procmaps(lul::LUL* aLUL)
|
||||
// to NotifyAfterMap().
|
||||
void* image = nullptr;
|
||||
size_t size = 0;
|
||||
bool ok = mapper.Map(&image, &size, nativeName);
|
||||
bool ok = mapper.Map(&image, &size, lib.GetName());
|
||||
if (ok && image && size > 0) {
|
||||
aLUL->NotifyAfterMap(lib.GetStart(), lib.GetEnd()-lib.GetStart(),
|
||||
nativeName.c_str(), image);
|
||||
} else if (!ok && lib.GetDebugName().IsEmpty()) {
|
||||
lib.GetName().c_str(), image);
|
||||
} else if (!ok && lib.GetName() == "") {
|
||||
// The object has no name and (as a consequence) the mapper
|
||||
// failed to map it. This happens on Linux, where
|
||||
// GetInfoForSelf() produces two such mappings: one for the
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <nsID.h>
|
||||
#include "nsString.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
class SharedLibrary {
|
||||
public:
|
||||
@@ -27,16 +25,12 @@ public:
|
||||
uintptr_t aEnd,
|
||||
uintptr_t aOffset,
|
||||
const std::string& aBreakpadId,
|
||||
const nsString& aName,
|
||||
const nsString& aDebugName,
|
||||
const std::string& aVersion)
|
||||
const std::string& aName)
|
||||
: mStart(aStart)
|
||||
, mEnd(aEnd)
|
||||
, mOffset(aOffset)
|
||||
, mBreakpadId(aBreakpadId)
|
||||
, mName(aName)
|
||||
, mDebugName(aDebugName)
|
||||
, mVersion(aVersion)
|
||||
{}
|
||||
|
||||
SharedLibrary(const SharedLibrary& aEntry)
|
||||
@@ -45,8 +39,6 @@ public:
|
||||
, mOffset(aEntry.mOffset)
|
||||
, mBreakpadId(aEntry.mBreakpadId)
|
||||
, mName(aEntry.mName)
|
||||
, mDebugName(aEntry.mDebugName)
|
||||
, mVersion(aEntry.mVersion)
|
||||
{}
|
||||
|
||||
SharedLibrary& operator=(const SharedLibrary& aEntry)
|
||||
@@ -59,8 +51,6 @@ public:
|
||||
mOffset = aEntry.mOffset;
|
||||
mBreakpadId = aEntry.mBreakpadId;
|
||||
mName = aEntry.mName;
|
||||
mDebugName = aEntry.mDebugName;
|
||||
mVersion = aEntry.mVersion;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -70,25 +60,14 @@ public:
|
||||
(mEnd == other.mEnd) &&
|
||||
(mOffset == other.mOffset) &&
|
||||
(mName == other.mName) &&
|
||||
(mDebugName == other.mDebugName) &&
|
||||
(mBreakpadId == other.mBreakpadId) &&
|
||||
(mVersion == other.mVersion);
|
||||
(mBreakpadId == other.mBreakpadId);
|
||||
}
|
||||
|
||||
uintptr_t GetStart() const { return mStart; }
|
||||
uintptr_t GetEnd() const { return mEnd; }
|
||||
uintptr_t GetOffset() const { return mOffset; }
|
||||
const std::string &GetBreakpadId() const { return mBreakpadId; }
|
||||
const nsString &GetName() const { return mName; }
|
||||
const std::string GetNativeDebugName() const {
|
||||
nsAutoCString debugNameStr;
|
||||
|
||||
NS_CopyUnicodeToNative(mDebugName, debugNameStr);
|
||||
|
||||
return debugNameStr.get();
|
||||
}
|
||||
const nsString &GetDebugName() const { return mDebugName; }
|
||||
const std::string &GetVersion() const { return mVersion; }
|
||||
const std::string &GetName() const { return mName; }
|
||||
|
||||
private:
|
||||
SharedLibrary() {}
|
||||
@@ -97,9 +76,7 @@ private:
|
||||
uintptr_t mEnd;
|
||||
uintptr_t mOffset;
|
||||
std::string mBreakpadId;
|
||||
nsString mName;
|
||||
nsString mDebugName;
|
||||
std::string mVersion;
|
||||
std::string mName;
|
||||
};
|
||||
|
||||
static bool
|
||||
|
||||
Reference in New Issue
Block a user