mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-23 08:49:23 +00:00
8f529f64f5
- Bug 932865 - Add ThreadHangStats for collecting background hang telemetry; r=vladan (2f08a076b)
- Bug 932865 - Add way for telemetry to iterate over active threads; r=froydnj (535615d3d)
- Bug 1128768: Part 3 - Update BHR to allow for hang annotations; r=vladan (0b880a667)
- Bug 935092 - Add ThreadStackHelper to get a thread's pesudo-stack; r=BenWa (1422cfe4d)
- Bug 942488 - Don't report pseudo-stacks without SPS profiler. r=nchen (e160a7a08)
- Bug 946817 - Don't assert mPseudoStack on B2G. r=BenWa (9f846df3b)
- Bug 951431 - Don't get stacks during profiler runs on Linux; r=BenWa (15036e907)
- Bug 978262 - Ignore duplicate frames when getting BHR stack. r=froydnj (964721b1b)
- Bug 985155 - Add signal trampoline on ARM Linux to work around kernel bug. r=snorp (cb8a7846c)
- Bug 995730 - Convert xpcom/threads/ to Gecko style. r=froydnj (fe150404e)
- Bug 1013326 - Distinguish chrome and content scripts in pseudostack; r=snorp (81273c977)
- Bug 1023461 - Remove temporary stack buffer in ThreadStackHelper; r=snorp (cf5a717c2)
- Bug 1023461 - Record filename and line number for chrome JS entries; r=snorp (10c89808f)
- Bug 1022456 - Fix modelines in xpcom/{base,glue,io,string,threads}/. (48dbc0416)
- Bug 1016441 - Switch to using real-time signal in ThreadStackHelper; (2c5f818be)
- Bug 1016629 - b. Use RAII class to assign mStackToFill; r=snorp (769eae130)
- Bug 1016629 - c. Add define for ThreadStackHelper pseudostack support; r=snorp (67def0d2f)
- Bug 1016629 - d. Add and implement GetNativeStack method in ThreadStackHelper; r=snorp r=jseward (46c52f2be)
- Bug 1016629 - e. Implement platform-specific code for filling in context; r=snorp r=jseward (e6a66858b)
- Bug 1016629 - g. Avoid ASan flag when copying stack; r=snorp (0159628b5)
- Bug 1045176 - Unbreak build on non-SPS platforms after bug 1016629. (f1d60d838)
- Bug 1047123 - ThreadStackHelper should use UniquePtr<uint8_t[]>, not ScopedDeleteArray. r=jchen (0e4af313c)
- Bug 1049161 - Fix ThreadStackHelper thread handle permissions on Windows; r=snorp (c05172b1c)
- Bug 1050185 - Make ThreadStackHelper::FillThreadContext Valgrind-friendly. r=nchen (368725774)
- Bug 1050440 - Remove repeated js::RunScript frames in ThreadStackHelper (2a79600b3)
- Bug 1046841 - Fix more style violations in previously touched .cpp files in xpcom/. r=froydnj (02afe2493)
- Bug 1069694 - Remove or move around functions in OldDebugAPI. r=shu (177197302)
- Bug 1069694 - Remove OldDebugAPI from the browser. r=shu (b8c917d42)
- Bug 1100911 - For MacOS builds running on Valgrind, make ThreadStackHelper::GetStack be a no-op. r=nchen. (d99c02e16)
- Bug 1091758 - Report full paths for most chrome scripts; r=snorp (2b72e7878)
- Bug 1109291 - Include better paths for hanging chrome scripts in profile extensions directory; r=snorp r=bsmedberg (1997b9532)
- Bug 1113416 - Don't read stack labels inside hang monitor sighandler; r=nfroyd r=snorp (9688f6069)
- bug 1146027 - more final r=froydnj (7b0f295e5)
- Bug 1164090 - Check for Windows path separator in BHR file name; r=snorp (f014b4d78)
- Bug 1169034 - include <cstdlib> in ThreadStackHelper.cpp to declare correct overload for std::abs; r=jseward (874d4447e)
- Bug 1182996 - Fix and add missing namespace comments. rs=ehsan (054fc00b2)
- Bug 932865 - Collect thread hang stats in BackgroundHangMonitor; (ac80c8e9f)
- minor anticipated fixes to get it compiling (2bd701d15)
231 lines
6.9 KiB
C++
231 lines
6.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sw=4 et tw=80:
|
|
*
|
|
* 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/. */
|
|
|
|
#ifndef mozilla_jsipc_JavaScriptLogging__
|
|
#define mozilla_jsipc_JavaScriptLogging__
|
|
|
|
#include "nsString.h"
|
|
#include "nsPrintfCString.h"
|
|
#include "jsfriendapi.h"
|
|
#include "jswrapper.h"
|
|
|
|
namespace mozilla {
|
|
namespace jsipc {
|
|
|
|
#define LOG(...) \
|
|
PR_BEGIN_MACRO \
|
|
if (LoggingEnabled()) { \
|
|
Logging log(this, cx); \
|
|
log.print(__VA_ARGS__); \
|
|
} \
|
|
PR_END_MACRO
|
|
|
|
#define LOG_STACK() \
|
|
PR_BEGIN_MACRO \
|
|
if (StackLoggingEnabled()) { \
|
|
js::DumpBacktrace(cx); \
|
|
} \
|
|
PR_END_MACRO
|
|
|
|
struct ReceiverObj
|
|
{
|
|
ObjectId id;
|
|
explicit ReceiverObj(ObjectId id) : id(id) {}
|
|
};
|
|
|
|
struct InVariant
|
|
{
|
|
JSVariant variant;
|
|
explicit InVariant(const JSVariant& variant) : variant(variant) {}
|
|
};
|
|
|
|
struct OutVariant
|
|
{
|
|
JSVariant variant;
|
|
explicit OutVariant(const JSVariant& variant) : variant(variant) {}
|
|
};
|
|
|
|
struct Identifier
|
|
{
|
|
JSIDVariant variant;
|
|
explicit Identifier(const JSIDVariant& variant) : variant(variant) {}
|
|
};
|
|
|
|
class Logging
|
|
{
|
|
public:
|
|
Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {}
|
|
|
|
void print(const nsCString& str) {
|
|
const char* side = shared->isParent() ? "from child" : "from parent";
|
|
printf("CPOW %s: %s\n", side, str.get());
|
|
}
|
|
|
|
void print(const char* str) {
|
|
print(nsCString(str));
|
|
}
|
|
template<typename T1>
|
|
void print(const char* fmt, const T1& a1) {
|
|
nsAutoCString tmp1;
|
|
format(a1, tmp1);
|
|
print(nsPrintfCString(fmt, tmp1.get()));
|
|
}
|
|
template<typename T1, typename T2>
|
|
void print(const char* fmt, const T1& a1, const T2& a2) {
|
|
nsAutoCString tmp1;
|
|
nsAutoCString tmp2;
|
|
format(a1, tmp1);
|
|
format(a2, tmp2);
|
|
print(nsPrintfCString(fmt, tmp1.get(), tmp2.get()));
|
|
}
|
|
template<typename T1, typename T2, typename T3>
|
|
void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) {
|
|
nsAutoCString tmp1;
|
|
nsAutoCString tmp2;
|
|
nsAutoCString tmp3;
|
|
format(a1, tmp1);
|
|
format(a2, tmp2);
|
|
format(a3, tmp3);
|
|
print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get()));
|
|
}
|
|
|
|
void format(const nsString& str, nsCString& out) {
|
|
out = NS_ConvertUTF16toUTF8(str);
|
|
}
|
|
|
|
void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) {
|
|
const char* side, *objDesc;
|
|
void* ptr;
|
|
|
|
if (local == incoming) {
|
|
JS::RootedObject obj(cx);
|
|
obj = shared->objects_.find(id);
|
|
if (obj) {
|
|
JSAutoCompartment ac(cx, obj);
|
|
objDesc = js::ObjectClassName(cx, obj);
|
|
} else {
|
|
objDesc = "<dead object>";
|
|
}
|
|
|
|
side = shared->isParent() ? "parent" : "child";
|
|
ptr = js::UncheckedUnwrap(obj, true);
|
|
} else {
|
|
objDesc = "<cpow>";
|
|
side = shared->isParent() ? "child" : "parent";
|
|
ptr = nullptr;
|
|
}
|
|
|
|
out = nsPrintfCString("<%s %s:%d:%p>", side, objDesc, id.serialNumber(), ptr);
|
|
}
|
|
|
|
void format(const ReceiverObj& obj, nsCString& out) {
|
|
formatObject(true, true, obj.id, out);
|
|
}
|
|
|
|
void format(const nsTArray<JSParam>& values, nsCString& out) {
|
|
nsAutoCString tmp;
|
|
out.Truncate();
|
|
for (size_t i = 0; i < values.Length(); i++) {
|
|
if (i)
|
|
out.AppendLiteral(", ");
|
|
if (values[i].type() == JSParam::Tvoid_t) {
|
|
out.AppendLiteral("<void>");
|
|
} else {
|
|
format(InVariant(values[i].get_JSVariant()), tmp);
|
|
out += tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
void format(const InVariant& value, nsCString& out) {
|
|
format(true, value.variant, out);
|
|
}
|
|
|
|
void format(const OutVariant& value, nsCString& out) {
|
|
format(false, value.variant, out);
|
|
}
|
|
|
|
void format(bool incoming, const JSVariant& value, nsCString& out) {
|
|
switch (value.type()) {
|
|
case JSVariant::TUndefinedVariant: {
|
|
out = "undefined";
|
|
break;
|
|
}
|
|
case JSVariant::TNullVariant: {
|
|
out = "null";
|
|
break;
|
|
}
|
|
case JSVariant::TnsString: {
|
|
nsAutoCString tmp;
|
|
format(value.get_nsString(), tmp);
|
|
out = nsPrintfCString("\"%s\"", tmp.get());
|
|
break;
|
|
}
|
|
case JSVariant::TObjectVariant: {
|
|
const ObjectVariant& ovar = value.get_ObjectVariant();
|
|
if (ovar.type() == ObjectVariant::TLocalObject)
|
|
formatObject(incoming, true, ObjectId::deserialize(ovar.get_LocalObject().serializedId()), out);
|
|
else
|
|
formatObject(incoming, false, ObjectId::deserialize(ovar.get_RemoteObject().serializedId()), out);
|
|
break;
|
|
}
|
|
case JSVariant::TSymbolVariant: {
|
|
out = "<Symbol>";
|
|
break;
|
|
}
|
|
case JSVariant::Tdouble: {
|
|
out = nsPrintfCString("%.0f", value.get_double());
|
|
break;
|
|
}
|
|
case JSVariant::Tbool: {
|
|
out = value.get_bool() ? "true" : "false";
|
|
break;
|
|
}
|
|
case JSVariant::TJSIID: {
|
|
out = "<JSIID>";
|
|
break;
|
|
}
|
|
default: {
|
|
out = "<JSIID>";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void format(const Identifier& id, nsCString& out) {
|
|
switch (id.variant.type()) {
|
|
case JSIDVariant::TSymbolVariant: {
|
|
out = "<Symbol>";
|
|
break;
|
|
}
|
|
case JSIDVariant::TnsString: {
|
|
nsAutoCString tmp;
|
|
format(id.variant.get_nsString(), tmp);
|
|
out = nsPrintfCString("\"%s\"", tmp.get());
|
|
break;
|
|
}
|
|
case JSIDVariant::Tint32_t: {
|
|
out = nsPrintfCString("%d", id.variant.get_int32_t());
|
|
break;
|
|
}
|
|
default: {
|
|
out = "Unknown";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
JavaScriptShared* shared;
|
|
JSContext* cx;
|
|
};
|
|
|
|
} // namespace jsipc
|
|
} // namespace mozilla
|
|
|
|
#endif
|