Merge b-i to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-10-02 12:51:02 -04:00
commit 8eb45d35cd
35 changed files with 240 additions and 226 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "52f7b7099a47ab3904a70d9a295ab0ed927ad59e",
"revision": "3e43be9b8c24802b40fdfbcf17895c4355e6d238",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="191d805f4911628d37a8a90a1e23a6013995138f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d711d1e469eeeecf25a02b2407a542a598918b2c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -9,6 +9,7 @@ var NotificationTest = (function () {
SimpleTest.waitForExplicitFinish();
// turn on testing pref (used by notification.cpp, and mock the alerts
SpecialPowers.setBoolPref("notification.prompt.testing", true);
SpecialPowers.setAllAppsLaunchable(true);
}
function teardown_testing_env() {

View File

@ -719,12 +719,14 @@ public:
}
private:
static void StackWalkCallback(void* aPc, void* aSp, void* aClosure)
static void StackWalkCallback(uint32_t aFrameNumber, void* aPc, void* aSp,
void* aClosure)
{
StackTrace* st = (StackTrace*) aClosure;
MOZ_ASSERT(st->mLength < MaxFrames);
st->mPcs[st->mLength] = aPc;
st->mLength++;
MOZ_ASSERT(st->mLength == aFrameNumber);
}
static int Cmp(const void* aA, const void* aB)
@ -755,7 +757,7 @@ StackTrace::Print(const Writer& aWriter, CodeAddressService* aLocService) const
static const size_t buflen = 1024;
char buf[buflen];
for (uint32_t i = 0; i < mLength; i++) {
aLocService->GetLocation(Pc(i), buf, buflen);
aLocService->GetLocation(i + 1, Pc(i), buf, buflen);
aWriter.Write(" %s\n", buf);
}
}
@ -1574,7 +1576,8 @@ Options::BadArg(const char* aArg)
#ifdef XP_MACOSX
static void
NopStackWalkCallback(void* aPc, void* aSp, void* aClosure)
NopStackWalkCallback(uint32_t aFrameNumber, void* aPc, void* aSp,
void* aClosure)
{
}
#endif

View File

@ -59,14 +59,15 @@ static uint32_t sStackTraceDepth = 0;
// NS_WalkStackCallback to write a formatted stack frame to an ostringstream.
static void
StackFrameToOStringStream(void* aPC, void* aSP, void* aClosure)
StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure)
{
std::ostringstream* stream = static_cast<std::ostringstream*>(aClosure);
nsCodeAddressDetails details;
char buf[1024];
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(aPC, &details, buf, sizeof(buf));
*stream << "--" << buf;
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
*stream << "--" << buf << '\n';
}
#endif

View File

@ -2,7 +2,7 @@
# 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/.
from marionette_test import MarionetteTestCase, skip_if_b2g
from marionette_test import MarionetteTestCase
from errors import JavascriptException, MarionetteException
class TestSpecialPowersContent(MarionetteTestCase):
@ -10,8 +10,6 @@ class TestSpecialPowersContent(MarionetteTestCase):
testpref = "testing.marionette.contentcharpref"
testvalue = "blabla"
# fails in b2g's test-container: "Error getting pref", Bug 1060061
@skip_if_b2g
def test_prefs(self):
result = self.marionette.execute_script("""
SpecialPowers.setCharPref("%(pref)s", "%(value)s");

View File

@ -13,6 +13,12 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Log.jsm");
let logger = Log.repository.getLogger("Marionette");
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
let specialpowers = {};
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
specialpowers);
//list of OOP frames that has the frame script loaded
let remoteFrames = [];
@ -121,6 +127,11 @@ FrameManager.prototype = {
if (frameMessageManager == mm) {
this.currentRemoteFrame = frame;
this.addMessageManagerListeners(mm);
if (!frame.specialPowersObserver) {
frame.specialPowersObserver = new specialpowers.SpecialPowersObserver();
frame.specialPowersObserver.init(mm);
}
mm.sendAsyncMessage("Marionette:restart", {});
return;
}
@ -135,6 +146,9 @@ FrameManager.prototype = {
aFrame.messageManager = Cu.getWeakReference(mm);
remoteFrames.push(aFrame);
this.currentRemoteFrame = aFrame;
aFrame.specialPowersObserver = new specialpowers.SpecialPowersObserver();
aFrame.specialPowersObserver.init(mm);
},
/*
@ -150,6 +164,20 @@ FrameManager.prototype = {
this.handledModal = false;
},
/**
* This function removes any SpecialPowersObservers from OOP frames.
*/
removeSpecialPowers: function FM_removeSpecialPowers() {
for (let i = 0; i < remoteFrames.length; i++) {
let frame = remoteFrames[i];
if (frame.specialPowersObserver) {
frame.specialPowersObserver.uninit();
frame.specialPowersObserver = null;
}
}
},
/**
* Adds message listeners to the server, listening for messages from content frame scripts.
* It also adds a "MarionetteFrame:getInterruptedState" message listener to the FrameManager,

View File

@ -2215,6 +2215,7 @@ MarionetteServerConnection.prototype = {
while (winEnum.hasMoreElements()) {
winEnum.getNext().messageManager.removeDelayedFrameScript(FRAME_SCRIPT);
}
this.curBrowser.frameManager.removeSpecialPowers();
this.curBrowser.frameManager.removeMessageManagerListeners(this.globalMessageManager);
}
this.switchToGlobalMessageManager();

View File

@ -75,21 +75,6 @@ if (outOfProcess) {
let mm = container.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
specialPowersObserver.init(mm);
mm.addMessageListener("SPPrefService", specialPowersObserver);
mm.addMessageListener("SPProcessCrashService", specialPowersObserver);
mm.addMessageListener("SPPingService", specialPowersObserver);
mm.addMessageListener("SpecialPowers.Quit", specialPowersObserver);
mm.addMessageListener("SpecialPowers.Focus", specialPowersObserver);
mm.addMessageListener("SPPermissionManager", specialPowersObserver);
mm.addMessageListener("SPObserverService", specialPowersObserver);
mm.addMessageListener("SPLoadChromeScript", specialPowersObserver);
mm.addMessageListener("SPChromeScriptMessage", specialPowersObserver);
mm.addMessageListener("SPQuotaManager", specialPowersObserver);
mm.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
mm.loadFrameScript(CHILD_SCRIPT_API, true);
mm.loadFrameScript(CHILD_SCRIPT, true);
//Workaround for bug 848411, once that bug is fixed, the following line can be removed
function contentScript() {
addEventListener("DOMWindowCreated", function listener(e) {
@ -99,8 +84,6 @@ if (outOfProcess) {
});
}
mm.loadFrameScript("data:,(" + encodeURI(contentScript.toSource()) + ")();", true);
specialPowersObserver._isFrameScriptLoaded = true;
}

View File

@ -50,25 +50,7 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
break;
case "chrome-document-global-created":
if (!this._isFrameScriptLoaded) {
// Register for any messages our API needs us to handle
this._messageManager.addMessageListener("SPPrefService", this);
this._messageManager.addMessageListener("SPProcessCrashService", this);
this._messageManager.addMessageListener("SPPingService", this);
this._messageManager.addMessageListener("SpecialPowers.Quit", this);
this._messageManager.addMessageListener("SpecialPowers.Focus", this);
this._messageManager.addMessageListener("SPPermissionManager", this);
this._messageManager.addMessageListener("SPWebAppService", this);
this._messageManager.addMessageListener("SPObserverService", this);
this._messageManager.addMessageListener("SPLoadChromeScript", this);
this._messageManager.addMessageListener("SPChromeScriptMessage", this);
this._messageManager.addMessageListener("SPQuotaManager", this);
this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT, true);
this._isFrameScriptLoaded = true;
}
this._loadFrameScript();
break;
case "http-on-modify-request":
@ -88,6 +70,29 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
}
};
SpecialPowersObserver.prototype._loadFrameScript = function()
{
if (!this._isFrameScriptLoaded) {
// Register for any messages our API needs us to handle
this._messageManager.addMessageListener("SPPrefService", this);
this._messageManager.addMessageListener("SPProcessCrashService", this);
this._messageManager.addMessageListener("SPPingService", this);
this._messageManager.addMessageListener("SpecialPowers.Quit", this);
this._messageManager.addMessageListener("SpecialPowers.Focus", this);
this._messageManager.addMessageListener("SPPermissionManager", this);
this._messageManager.addMessageListener("SPWebAppService", this);
this._messageManager.addMessageListener("SPObserverService", this);
this._messageManager.addMessageListener("SPLoadChromeScript", this);
this._messageManager.addMessageListener("SPChromeScriptMessage", this);
this._messageManager.addMessageListener("SPQuotaManager", this);
this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT, true);
this._isFrameScriptLoaded = true;
}
};
SpecialPowersObserver.prototype._sendAsyncMessage = function(msgname, msg)
{
if (this._mmIsGlobal) {
@ -112,6 +117,8 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
if (messageManager) {
this._messageManager = messageManager;
this._mmIsGlobal = false;
this._loadFrameScript();
}
};

View File

@ -56,14 +56,15 @@ static const int kClientChannelFd = 3;
extern "C" {
static void PrintStackFrame(void *aPC, void *aSP, void *aClosure)
static void PrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
void *aClosure)
{
char buf[1024];
nsCodeAddressDetails details;
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(aPC, &details, buf, sizeof(buf));
fputs(buf, stdout);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
fprintf(stdout, "%s\n", buf);
}
}

View File

@ -543,7 +543,8 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
#ifdef USE_NS_STACKWALK
static
void StackWalkCallback(void* aPC, void* aSP, void* aClosure)
void StackWalkCallback(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure)
{
NativeStack* nativeStack = static_cast<NativeStack*>(aClosure);
MOZ_ASSERT(nativeStack->count < nativeStack->size);
@ -567,8 +568,11 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
0
};
// Start with the current function.
StackWalkCallback(aSample->pc, aSample->sp, &nativeStack);
// Start with the current function. We use 0 as the frame number here because
// the FramePointerStackWalk() and NS_StackWalk() calls below will use 1..N.
// This is a bit weird but it doesn't matter because StackWalkCallback()
// doesn't use the frame number argument.
StackWalkCallback(/* frameNumber */ 0, aSample->pc, aSample->sp, &nativeStack);
uint32_t maxFrames = uint32_t(nativeStack.size - nativeStack.count);
#ifdef XP_MACOSX

View File

@ -4,18 +4,9 @@
# 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/.
# This script uses addr2line (part of binutils) to process the output of
# nsTraceRefcnt's Linux stack walking code. This is useful for two
# things:
# (1) Getting line number information out of
# |nsTraceRefcnt::WalkTheStack|'s output in debug builds.
# (2) Getting function names out of |nsTraceRefcnt::WalkTheStack|'s
# output on optimized builds (where it mostly prints UNKNOWN
# because only a handful of symbols are exported from component
# libraries).
#
# Use the script by piping output containing stacks (such as raw stacks
# or make-tree.pl balance trees) through this script.
# This script uses addr2line (part of binutils) to post-process the entries
# produced by NS_FormatCodeAddress(), which on Linux often lack a function
# name, a file name and a line number.
import subprocess
import sys
@ -296,25 +287,20 @@ def addressToSymbol(file, address):
cache[address] = result
return result
line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9A-F]{1,8})\](.*)$")
balance_tree_re = re.compile("^([ \|0-9-]*)(.*)$")
# Matches lines produced by NS_FormatCodeAddress().
line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
def fixSymbols(line):
result = line_re.match(line)
if result is not None:
# before allows preservation of balance trees
# after allows preservation of counts
(before, file, address, after) = result.groups()
(before, fn, file, address, after) = result.groups()
if os.path.exists(file) and os.path.isfile(file):
# throw away the bad symbol, but keep balance tree structure
(before, badsymbol) = balance_tree_re.match(before).groups()
(name, fileline) = addressToSymbol(file, address)
# If addr2line gave us something useless, keep what we had before.
if name == "??":
name = badsymbol
name = fn
if fileline == "??:0" or fileline == "??:?":
fileline = file

View File

@ -4,16 +4,9 @@
# 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/.
# This script uses atos to process the output of nsTraceRefcnt's Mac OS
# X stack walking code. This is useful for two things:
# (1) Getting line number information out of
# |nsTraceRefcnt::WalkTheStack|'s output in debug builds.
# (2) Getting function names out of |nsTraceRefcnt::WalkTheStack|'s
# output on all builds (where it mostly prints UNKNOWN because only
# a handful of symbols are exported from component libraries).
#
# Use the script by piping output containing stacks (such as raw stacks
# or make-tree.pl balance trees) through this script.
# This script uses |atos| to post-process the entries produced by
# NS_FormatCodeAddress(), which on Mac often lack a file name and a line
# number.
import subprocess
import sys
@ -99,16 +92,14 @@ def cxxfilt(sym):
cxxfilt_proc.stdin.write(sym + "\n")
return cxxfilt_proc.stdout.readline().rstrip("\n")
line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9a-fA-F]{1,8})\](.*)$")
balance_tree_re = re.compile("^([ \|0-9-]*)")
# Matches lines produced by NS_FormatCodeAddress().
line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
atos_name_re = re.compile("^(.+) \(in ([^)]+)\) \((.+)\)$")
def fixSymbols(line):
result = line_re.match(line)
if result is not None:
# before allows preservation of balance trees
# after allows preservation of counts
(before, file, address, after) = result.groups()
(before, fn, file, address, after) = result.groups()
address = int(address, 16)
if os.path.exists(file) and os.path.isfile(file):
@ -129,9 +120,6 @@ def fixSymbols(line):
name = cxxfilt(name)
info = "%s (%s, in %s)" % (name, fileline, library)
# throw away the bad symbol, but keep balance tree structure
before = balance_tree_re.match(before).groups()[0]
nl = '\n' if line[-1] == '\n' else ''
return before + info + after + nl
else:

View File

@ -4,6 +4,10 @@
# 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/.
# This script uses breakpad symbols to post-process the entries produced by
# NS_FormatCodeAddress(), which on TBPL builds often lack a file name and a
# line number (and on Linux even the symbol is often bad).
from __future__ import with_statement
import sys
@ -112,18 +116,14 @@ def addressToSymbol(file, address, symbolsDir):
else:
return ""
line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9A-F]{1,16})\](.*)$")
balance_tree_re = re.compile("^([ \|0-9-]*)")
# Matches lines produced by NS_FormatCodeAddress().
line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
def fixSymbols(line, symbolsDir):
result = line_re.match(line)
if result is not None:
# before allows preservation of balance trees
# after allows preservation of counts
(before, file, address, after) = result.groups()
(before, fn, file, address, after) = result.groups()
address = int(address, 16)
# throw away the bad symbol, but keep balance tree structure
before = balance_tree_re.match(before).groups()[0]
symbol = addressToSymbol(file, address, symbolsDir)
if not symbol:
symbol = "%s + 0x%x" % (os.path.basename(file), address)

View File

@ -97,11 +97,16 @@ sub read_data($$$) {
my $cnt = shift(@fields);
# Collect the remaining lines to create a stack trace.
# Collect the remaining lines to create a stack trace. We need to
# filter out the frame numbers so that frames that differ only in
# their frame number are considered equivalent. However, we need to
# keep a frame number on each line so that the fix*.py scripts can
# parse the output. So we set the frame number to 0 for every frame.
my @stack;
CALLSITE: while (<$INFILE>) {
chomp;
last CALLSITE if (/^$/);
$_ =~ s/#\d+: /#00: /; # replace frame number with 0
$stack[++$#stack] = $_;
}

View File

@ -893,7 +893,7 @@ calltree(void **stack, size_t num_stack_entries, tm_thread *t)
* reverse it in calltree.
*/
static void
stack_callback(void *pc, void *sp, void *closure)
stack_callback(uint32_t frameNumber, void *pc, void *sp, void *closure)
{
stack_buffer_info *info = (stack_buffer_info*) closure;

View File

@ -89,12 +89,9 @@ class CodeAddressService
// Convert "" to nullptr. Otherwise, make a copy of the name.
StringAlloc::free(mFunction);
mFunction =
!aFunction[0] ? nullptr : StringAlloc::copy(aFunction);
mFunction = !aFunction[0] ? nullptr : StringAlloc::copy(aFunction);
StringAlloc::free(mFileName);
mFileName =
!aFileName[0] ? nullptr : StringAlloc::copy(aFileName);
mFileName = !aFileName[0] ? nullptr : StringAlloc::copy(aFileName);
mLibrary = aLibrary;
mLOffset = aLOffset;
@ -132,7 +129,8 @@ public:
{
}
void GetLocation(const void* aPc, char* aBuf, size_t aBufLen)
void GetLocation(uint32_t aFrameNumber, const void* aPc, char* aBuf,
size_t aBufLen)
{
MOZ_ASSERT(DescribeCodeAddressLock::IsLocked());
@ -165,26 +163,9 @@ public:
MOZ_ASSERT(entry.mPc == aPc);
uintptr_t entryPc = (uintptr_t)(entry.mPc);
// Sometimes we get nothing useful. Just print "???" for the entire entry
// so that fix_linux_stack.py doesn't complain about an empty filename.
if (!entry.mFunction && !entry.mLibrary[0] && entry.mLOffset == 0) {
snprintf(aBuf, aBufLen, "??? 0x%" PRIxPTR, entryPc);
} else {
// Use "???" for unknown functions.
const char* entryFunction = entry.mFunction ? entry.mFunction : "???";
if (entry.mFileName) {
// On Windows we can get the filename and line number at runtime.
snprintf(aBuf, aBufLen, "%s (%s:%u) 0x%" PRIxPTR,
entryFunction, entry.mFileName, entry.mLineNo, entryPc);
} else {
// On Linux and Mac we cannot get the filename and line number at
// runtime, so we print the offset in a form that fix_linux_stack.py and
// fix_macosx_stack.py can post-process.
snprintf(aBuf, aBufLen, "%s[%s +0x%" PRIXPTR "] 0x%" PRIxPTR,
entryFunction, entry.mLibrary, entry.mLOffset, entryPc);
}
}
NS_FormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
entry.mFunction, entry.mLibrary, entry.mLOffset,
entry.mFileName, entry.mLineNo);
}
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const

View File

@ -13,6 +13,10 @@
#include "nsStackWalk.h"
#ifdef XP_WIN
#define snprintf _snprintf
#endif
using namespace mozilla;
// The presence of this address is the stack must stop the stack walk. If
@ -54,7 +58,7 @@ malloc_logger_t(uint32_t aType,
extern malloc_logger_t* malloc_logger;
static void
stack_callback(void* aPc, void* aSp, void* aClosure)
stack_callback(uint32_t aFrameNumber, void* aPc, void* aSp, void* aClosure)
{
const char* name = static_cast<char*>(aClosure);
Dl_info info;
@ -612,7 +616,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
::CloseHandle(myThread);
for (uint32_t i = 0; i < data.pc_count; ++i) {
(*aCallback)(data.pcs[i], data.sps[i], aClosure);
(*aCallback)(i + 1, data.pcs[i], data.sps[i], aClosure);
}
return data.pc_count == 0 ? NS_ERROR_FAILURE : NS_OK;
@ -827,38 +831,6 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
return NS_OK;
}
EXPORT_XPCOM_API(nsresult)
NS_FormatCodeAddressDetails(void* aPC, const nsCodeAddressDetails* aDetails,
char* aBuffer, uint32_t aBufferSize)
{
if (aDetails->function[0]) {
_snprintf(aBuffer, aBufferSize, "%s+0x%08lX [%s +0x%016lX]",
aDetails->function, aDetails->foffset,
aDetails->library, aDetails->loffset);
} else if (aDetails->library[0]) {
_snprintf(aBuffer, aBufferSize, "UNKNOWN [%s +0x%016lX]",
aDetails->library, aDetails->loffset);
} else {
_snprintf(aBuffer, aBufferSize, "UNKNOWN 0x%016lX", aPC);
}
aBuffer[aBufferSize - 1] = '\0';
uint32_t len = strlen(aBuffer);
if (aDetails->filename[0]) {
_snprintf(aBuffer + len, aBufferSize - len, " (%s, line %d)\n",
aDetails->filename, aDetails->lineno);
} else {
aBuffer[len] = '\n';
if (++len != aBufferSize) {
aBuffer[len] = '\0';
}
}
aBuffer[aBufferSize - 2] = '\n';
aBuffer[aBufferSize - 1] = '\0';
return NS_OK;
}
// i386 or PPC Linux stackwalking code
#elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || NSSTACKWALK_SUPPORTS_LINUX || NSSTACKWALK_SUPPORTS_MACOSX)
@ -947,8 +919,8 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
// it called. We can't know the exact location of the SP
// but this should be sufficient for our use the SP
// to order elements on the stack.
(*aCallback)(pc, bp, aClosure);
numFrames++;
(*aCallback)(numFrames, pc, bp, aClosure);
if (aMaxFrames != 0 && numFrames == aMaxFrames) {
break;
}
@ -991,7 +963,6 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
#endif
return FramePointerStackWalk(aCallback, aSkipFrames, aMaxFrames,
aClosure, bp, stackEnd);
}
#elif defined(HAVE__UNWIND_BACKTRACE)
@ -1023,8 +994,8 @@ unwind_callback(struct _Unwind_Context* context, void* closure)
return _URC_FOREIGN_EXCEPTION_CAUGHT;
}
if (--info->skip < 0) {
(*info->callback)(pc, nullptr, info->closure);
info->numFrames++;
(*info->callback)(info->numFrames, pc, nullptr, info->closure);
if (info->maxFrames != 0 && info->numFrames == info->maxFrames) {
// Again, any error code that stops the walk will do.
return _URC_FOREIGN_EXCEPTION_CAUGHT;
@ -1102,24 +1073,6 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
return NS_OK;
}
EXPORT_XPCOM_API(nsresult)
NS_FormatCodeAddressDetails(void* aPC, const nsCodeAddressDetails* aDetails,
char* aBuffer, uint32_t aBufferSize)
{
if (!aDetails->library[0]) {
snprintf(aBuffer, aBufferSize, "UNKNOWN %p\n", aPC);
} else if (!aDetails->function[0]) {
snprintf(aBuffer, aBufferSize, "UNKNOWN [%s +0x%08" PRIXPTR "]\n",
aDetails->library, aDetails->loffset);
} else {
snprintf(aBuffer, aBufferSize, "%s+0x%08" PRIXPTR
" [%s +0x%08" PRIXPTR "]\n",
aDetails->function, aDetails->foffset,
aDetails->library, aDetails->loffset);
}
return NS_OK;
}
#else // unsupported platform.
EXPORT_XPCOM_API(nsresult)
@ -1153,12 +1106,44 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
return NS_ERROR_NOT_IMPLEMENTED;
}
EXPORT_XPCOM_API(nsresult)
NS_FormatCodeAddressDetails(void* aPC, const nsCodeAddressDetails* aDetails,
char* aBuffer, uint32_t aBufferSize)
#endif
EXPORT_XPCOM_API(void)
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
uint32_t aFrameNumber, void* aPC,
const nsCodeAddressDetails* aDetails)
{
aBuffer[0] = '\0';
return NS_ERROR_NOT_IMPLEMENTED;
NS_FormatCodeAddress(aBuffer, aBufferSize,
aFrameNumber, aPC, aDetails->function,
aDetails->library, aDetails->loffset,
aDetails->filename, aDetails->lineno);
}
EXPORT_XPCOM_API(void)
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
const void* aPC, const char* aFunction,
const char* aLibrary, ptrdiff_t aLOffset,
const char* aFileName, uint32_t aLineNo)
{
const char* function = aFunction && aFunction[0] ? aFunction : "???";
if (aFileName && aFileName[0]) {
// We have a filename and (presumably) a line number. Use them.
snprintf(aBuffer, aBufferSize,
"#%02u: %s (%s:%u)",
aFrameNumber, function, aFileName, aLineNo);
} else if (aLibrary && aLibrary[0]) {
// We have no filename, but we do have a library name. Use it and the
// library offset, and print them in a way that scripts like
// fix_{linux,macosx}_stacks.py can easily post-process.
snprintf(aBuffer, aBufferSize,
"#%02u: %s[%s +0x%" PRIxPTR "]",
aFrameNumber, function, aLibrary, aLOffset);
} else {
// We have nothing useful to go on. (The format string is split because
// '??)' is a trigraph and causes a warning, sigh.)
snprintf(aBuffer, aBufferSize,
"#%02u: ??? (???:???" ")",
aFrameNumber);
}
}
#endif

View File

@ -18,11 +18,20 @@
extern "C" {
#endif
// aSP will be the best approximation possible of what the stack pointer will be
// pointing to when the execution returns to executing that at that PC.
// If no approximation can be made it will be nullptr.
/**
* The callback for NS_StackWalk.
*
* @param aFrameNumber The frame number (starts at 1, not 0).
* @param aPC The program counter value.
* @param aSP The best approximation possible of what the stack
* pointer will be pointing to when the execution returns
* to executing that at aPC. If no approximation can
* be made it will be nullptr.
* @param aClosure Extra data passed in via NS_StackWalk().
*/
typedef void
(*NS_WalkStackCallback)(void* aPC, void* aSP, void* aClosure);
(*NS_WalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure);
/**
* Call aCallback for the C/C++ stack frames on the current thread, from
@ -109,19 +118,50 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails);
* these are not available, library and offset should be reported, if
* possible.
*
* @param aPC The code address.
* @param aDetails The value filled in by NS_DescribeCodeAddress(aPC).
* @param aBuffer A string to be filled in with the description.
* The string will always be null-terminated.
* @param aBufferSize The size, in bytes, of aBuffer, including
* room for the terminating null. If the information
* to be printed would be larger than aBuffer, it
* will be truncated so that aBuffer[aBufferSize-1]
* is the terminating null.
* Note that this output is parsed by several scripts including the fix*.py and
* make-tree.pl scripts in tools/rb/. It should only be change with care, and
* in conjunction with those scripts.
*
* @param aBuffer A string to be filled in with the description.
* The string will always be null-terminated.
* @param aBufferSize The size, in bytes, of aBuffer, including
* room for the terminating null. If the information
* to be printed would be larger than aBuffer, it
* will be truncated so that aBuffer[aBufferSize-1]
* is the terminating null.
* @param aFrameNumber The frame number.
* @param aPC The code address.
* @param aFunction The function name. Possibly null or the empty string.
* @param aLibrary The library name. Possibly null or the empty string.
* @param aLOffset The library offset.
* @param aFileName The filename. Possibly null or the empty string.
* @param aLineNo The line number. Possibly zero.
*/
XPCOM_API(nsresult)
NS_FormatCodeAddressDetails(void* aPC, const nsCodeAddressDetails* aDetails,
char* aBuffer, uint32_t aBufferSize);
XPCOM_API(void)
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
const void* aPC, const char* aFunction,
const char* aLibrary, ptrdiff_t aLOffset,
const char* aFileName, uint32_t aLineNo);
/**
* Format the information about a code address in the same fashion as
* NS_FormatCodeAddress.
*
* @param aBuffer A string to be filled in with the description.
* The string will always be null-terminated.
* @param aBufferSize The size, in bytes, of aBuffer, including
* room for the terminating null. If the information
* to be printed would be larger than aBuffer, it
* will be truncated so that aBuffer[aBufferSize-1]
* is the terminating null.
* @param aFrameNumber The frame number.
* @param aPC The code address.
* @param aDetails The value filled in by NS_DescribeCodeAddress(aPC).
*/
XPCOM_API(void)
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
uint32_t aFrameNumber, void* aPC,
const nsCodeAddressDetails* aDetails);
#ifdef __cplusplus
}

View File

@ -929,24 +929,25 @@ extern "C" {
#ifdef MOZ_STACKWALKING
static void
PrintStackFrame(void* aPC, void* aSP, void* aClosure)
PrintStackFrame(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
{
FILE* stream = (FILE*)aClosure;
nsCodeAddressDetails details;
char buf[1024];
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(aPC, &details, buf, sizeof(buf));
fputs(buf, stream);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
fprintf(stream, "%s\n", buf);
}
static void
PrintStackFrameCached(void* aPC, void* aSP, void* aClosure)
PrintStackFrameCached(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure)
{
auto stream = static_cast<FILE*>(aClosure);
static const size_t buflen = 1024;
char buf[buflen];
gCodeAddressService->GetLocation(aPC, buf, buflen);
gCodeAddressService->GetLocation(aFrameNumber, aPC, buf, buflen);
fprintf(stream, " %s\n", buf);
}
#endif

View File

@ -79,7 +79,7 @@ private:
};
static void
RecordStackWalker(void* aPC, void* aSP, void* aClosure)
RecordStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
{
std::vector<uintptr_t>* stack =
static_cast<std::vector<uintptr_t>*>(aClosure);

View File

@ -48,7 +48,8 @@ BlockingResourceBase::DDT* BlockingResourceBase::sDeadlockDetector;
void
BlockingResourceBase::StackWalkCallback(void* aPc, void* aSp, void* aClosure)
BlockingResourceBase::StackWalkCallback(uint32_t aFrameNumber, void* aPc,
void* aSp, void* aClosure)
{
#ifndef MOZ_CALLSTACK_DISABLED
AcquisitionState* state = (AcquisitionState*)aClosure;
@ -67,8 +68,7 @@ BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
// NB: Ignore the return value, there's nothing useful we can do if this
// this fails.
NS_StackWalk(StackWalkCallback, kSkipFrames,
24, &aState, 0, nullptr);
NS_StackWalk(StackWalkCallback, kSkipFrames, 24, &aState, 0, nullptr);
#endif
}
@ -185,7 +185,7 @@ BlockingResourceBase::Print(nsACString& aOut) const
WalkTheStackCodeAddressService addressService;
for (uint32_t i = 0; i < state.Length(); i++) {
const size_t kMaxLength = 4096;
const size_t kMaxLength = 1024;
char buffer[kMaxLength];
addressService.GetLocation(state[i], buffer, kMaxLength);
const char* fmt = " %s\n";

View File

@ -319,7 +319,8 @@ private:
*/
static void Shutdown();
static void StackWalkCallback(void* aPc, void* aSp, void* aClosure);
static void StackWalkCallback(uint32_t aFrameNumber, void* aPc,
void* aSp, void* aClosure);
static void GetStackTrace(AcquisitionState& aState);
# ifdef MOZILLA_INTERNAL_API

View File

@ -114,7 +114,7 @@ Crash()
#ifdef REPORT_CHROME_HANGS
static void
ChromeStackWalker(void* aPC, void* aSP, void* aClosure)
ChromeStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
{
MOZ_ASSERT(aClosure);
std::vector<uintptr_t>* stack =