зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334278 - have FormatStackDump return UniqueChars; r=froydnj
Change FormatStackDump to return UniqueChars and fix up the users. This removes a bit more manual memory management. MozReview-Commit-ID: 60GBgeS4rzg --HG-- extra : rebase_source : 15060321f567816ca434cdf1ef816d8322ceefff
This commit is contained in:
Родитель
bcbdcb14bb
Коммит
3e96a70858
|
@ -2841,14 +2841,13 @@ GetBacktrace(JSContext* cx, unsigned argc, Value* vp)
|
||||||
showThisProps = ToBoolean(v);
|
showThisProps = ToBoolean(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
JS::UniqueChars buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RootedString str(cx);
|
RootedString str(cx);
|
||||||
if (!(str = JS_NewStringCopyZ(cx, buf)))
|
if (!(str = JS_NewStringCopyZ(cx, buf.get())))
|
||||||
return false;
|
return false;
|
||||||
JS_smprintf_free(buf);
|
|
||||||
|
|
||||||
args.rval().setString(str);
|
args.rval().setString(str);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -784,14 +784,14 @@ FormatValue(JSContext* cx, const Value& vArg, JSAutoByteString& bytes)
|
||||||
|
|
||||||
// Wrapper for JS_sprintf_append() that reports allocation failure to the
|
// Wrapper for JS_sprintf_append() that reports allocation failure to the
|
||||||
// context.
|
// context.
|
||||||
static char*
|
static JS::UniqueChars
|
||||||
MOZ_FORMAT_PRINTF(3, 4)
|
MOZ_FORMAT_PRINTF(3, 4)
|
||||||
sprintf_append(JSContext* cx, char* buf, const char* fmt, ...)
|
sprintf_append(JSContext* cx, JS::UniqueChars&& buf, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
char* result = JS_vsprintf_append(UniqueChars(buf), fmt, ap).release();
|
JS::UniqueChars result = JS_vsprintf_append(Move(buf), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -802,8 +802,8 @@ sprintf_append(JSContext* cx, char* buf, const char* fmt, ...)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static JS::UniqueChars
|
||||||
FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
|
||||||
bool showArgs, bool showLocals, bool showThisProps)
|
bool showArgs, bool showLocals, bool showThisProps)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!cx->isExceptionPending());
|
MOZ_ASSERT(!cx->isExceptionPending());
|
||||||
|
@ -831,16 +831,17 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the frame number and function name
|
// print the frame number and function name
|
||||||
|
JS::UniqueChars buf(Move(inBuf));
|
||||||
if (funname) {
|
if (funname) {
|
||||||
JSAutoByteString funbytes;
|
JSAutoByteString funbytes;
|
||||||
char* str = funbytes.encodeLatin1(cx, funname);
|
char* str = funbytes.encodeLatin1(cx, funname);
|
||||||
if (!str)
|
if (!str)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
buf = sprintf_append(cx, buf, "%d %s(", num, str);
|
buf = sprintf_append(cx, Move(buf), "%d %s(", num, str);
|
||||||
} else if (fun) {
|
} else if (fun) {
|
||||||
buf = sprintf_append(cx, buf, "%d anonymous(", num);
|
buf = sprintf_append(cx, Move(buf), "%d anonymous(", num);
|
||||||
} else {
|
} else {
|
||||||
buf = sprintf_append(cx, buf, "%d <TOP LEVEL>", num);
|
buf = sprintf_append(cx, Move(buf), "%d <TOP LEVEL>", num);
|
||||||
}
|
}
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -889,7 +890,7 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
buf = sprintf_append(cx, buf, "%s%s%s%s%s%s",
|
buf = sprintf_append(cx, Move(buf), "%s%s%s%s%s%s",
|
||||||
!first ? ", " : "",
|
!first ? ", " : "",
|
||||||
name ? name :"",
|
name ? name :"",
|
||||||
name ? " = " : "",
|
name ? " = " : "",
|
||||||
|
@ -901,7 +902,7 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
buf = sprintf_append(cx, buf,
|
buf = sprintf_append(cx, Move(buf),
|
||||||
" <Failed to get argument while inspecting stack frame>\n");
|
" <Failed to get argument while inspecting stack frame>\n");
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -911,7 +912,7 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
// print filename and line number
|
// print filename and line number
|
||||||
buf = sprintf_append(cx, buf, "%s [\"%s\":%d]\n",
|
buf = sprintf_append(cx, Move(buf), "%s [\"%s\":%d]\n",
|
||||||
fun ? ")" : "",
|
fun ? ")" : "",
|
||||||
filename ? filename : "<unknown>",
|
filename ? filename : "<unknown>",
|
||||||
lineno);
|
lineno);
|
||||||
|
@ -936,9 +937,9 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
const char* str = thisValBytes.encodeLatin1(cx, thisValStr);
|
const char* str = thisValBytes.encodeLatin1(cx, thisValStr);
|
||||||
if (!str)
|
if (!str)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
buf = sprintf_append(cx, buf, " this = %s\n", str);
|
buf = sprintf_append(cx, Move(buf), " this = %s\n", str);
|
||||||
} else {
|
} else {
|
||||||
buf = sprintf_append(cx, buf, " <failed to get 'this' value>\n");
|
buf = sprintf_append(cx, Move(buf), " <failed to get 'this' value>\n");
|
||||||
}
|
}
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -965,7 +966,7 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
if (cx->isThrowingOutOfMemory())
|
if (cx->isThrowingOutOfMemory())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
cx->clearPendingException();
|
cx->clearPendingException();
|
||||||
buf = sprintf_append(cx, buf,
|
buf = sprintf_append(cx, Move(buf),
|
||||||
" <Failed to fetch property while inspecting stack frame>\n");
|
" <Failed to fetch property while inspecting stack frame>\n");
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -989,13 +990,13 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name && value) {
|
if (name && value) {
|
||||||
buf = sprintf_append(cx, buf, " this.%s = %s%s%s\n",
|
buf = sprintf_append(cx, Move(buf), " this.%s = %s%s%s\n",
|
||||||
name,
|
name,
|
||||||
v.isString() ? "\"" : "",
|
v.isString() ? "\"" : "",
|
||||||
value,
|
value,
|
||||||
v.isString() ? "\"" : "");
|
v.isString() ? "\"" : "");
|
||||||
} else {
|
} else {
|
||||||
buf = sprintf_append(cx, buf,
|
buf = sprintf_append(cx, Move(buf),
|
||||||
" <Failed to format values while inspecting stack frame>\n");
|
" <Failed to format values while inspecting stack frame>\n");
|
||||||
}
|
}
|
||||||
if (!buf)
|
if (!buf)
|
||||||
|
@ -1007,22 +1008,23 @@ FormatFrame(JSContext* cx, const FrameIter& iter, char* buf, int num,
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static JS::UniqueChars
|
||||||
FormatWasmFrame(JSContext* cx, const FrameIter& iter, char* buf, int num, bool showArgs)
|
FormatWasmFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
|
||||||
|
bool showArgs)
|
||||||
{
|
{
|
||||||
JSAtom* functionDisplayAtom = iter.functionDisplayAtom();
|
JSAtom* functionDisplayAtom = iter.functionDisplayAtom();
|
||||||
UniqueChars nameStr;
|
UniqueChars nameStr;
|
||||||
if (functionDisplayAtom)
|
if (functionDisplayAtom)
|
||||||
nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom);
|
nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom);
|
||||||
|
|
||||||
buf = sprintf_append(cx, buf, "%d %s()",
|
JS::UniqueChars buf = sprintf_append(cx, Move(inBuf), "%d %s()",
|
||||||
num,
|
num,
|
||||||
nameStr ? nameStr.get() : "<wasm-function>");
|
nameStr ? nameStr.get() : "<wasm-function>");
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const char* filename = iter.filename();
|
const char* filename = iter.filename();
|
||||||
uint32_t lineno = iter.computeLine();
|
uint32_t lineno = iter.computeLine();
|
||||||
buf = sprintf_append(cx, buf, " [\"%s\":%d]\n",
|
buf = sprintf_append(cx, Move(buf), " [\"%s\":%d]\n",
|
||||||
filename ? filename : "<unknown>",
|
filename ? filename : "<unknown>",
|
||||||
lineno);
|
lineno);
|
||||||
|
|
||||||
|
@ -1030,23 +1032,25 @@ FormatWasmFrame(JSContext* cx, const FrameIter& iter, char* buf, int num, bool s
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(char*)
|
JS_FRIEND_API(JS::UniqueChars)
|
||||||
JS::FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps)
|
JS::FormatStackDump(JSContext* cx, JS::UniqueChars&& inBuf, bool showArgs, bool showLocals,
|
||||||
|
bool showThisProps)
|
||||||
{
|
{
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
|
JS::UniqueChars buf(Move(inBuf));
|
||||||
for (AllFramesIter i(cx); !i.done(); ++i) {
|
for (AllFramesIter i(cx); !i.done(); ++i) {
|
||||||
if (i.hasScript())
|
if (i.hasScript())
|
||||||
buf = FormatFrame(cx, i, buf, num, showArgs, showLocals, showThisProps);
|
buf = FormatFrame(cx, i, Move(buf), num, showArgs, showLocals, showThisProps);
|
||||||
else
|
else
|
||||||
buf = FormatWasmFrame(cx, i, buf, num, showArgs);
|
buf = FormatWasmFrame(cx, i, Move(buf), num, showArgs);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!num)
|
if (!num)
|
||||||
buf = JS_sprintf_append(UniqueChars(buf), "JavaScript stack is empty\n").release();
|
buf = JS_sprintf_append(Move(buf), "JavaScript stack is empty\n");
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,8 +267,9 @@ DumpBacktrace(JSContext* cx);
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
/** Exposed for DumpJSStack */
|
/** Exposed for DumpJSStack */
|
||||||
extern JS_FRIEND_API(char*)
|
extern JS_FRIEND_API(JS::UniqueChars)
|
||||||
FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps);
|
FormatStackDump(JSContext* cx, JS::UniqueChars&& buf, bool showArgs, bool showLocals,
|
||||||
|
bool showThisProps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set all of the uninitialized lexicals on an object to undefined. Return
|
* Set all of the uninitialized lexicals on an object to undefined. Return
|
||||||
|
|
|
@ -4205,13 +4205,12 @@ StackDump(JSContext* cx, unsigned argc, Value* vp)
|
||||||
bool showLocals = ToBoolean(args.get(1));
|
bool showLocals = ToBoolean(args.get(1));
|
||||||
bool showThisProps = ToBoolean(args.get(2));
|
bool showThisProps = ToBoolean(args.get(2));
|
||||||
|
|
||||||
char* buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
JS::UniqueChars buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
fputs("Failed to format JavaScript stack for dump\n", gOutFile->fp);
|
fputs("Failed to format JavaScript stack for dump\n", gOutFile->fp);
|
||||||
JS_ClearPendingException(cx);
|
JS_ClearPendingException(cx);
|
||||||
} else {
|
} else {
|
||||||
fputs(buf, gOutFile->fp);
|
fputs(buf.get(), gOutFile->fp);
|
||||||
JS_smprintf_free(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.rval().setUndefined();
|
args.rval().setUndefined();
|
||||||
|
|
|
@ -41,20 +41,19 @@ xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps)
|
||||||
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
|
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
|
||||||
if (!cx) {
|
if (!cx) {
|
||||||
printf("there is no JSContext on the stack!\n");
|
printf("there is no JSContext on the stack!\n");
|
||||||
} else if (char* buf = xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps)) {
|
} else if (JS::UniqueChars buf = xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps)) {
|
||||||
DebugDump("%s\n", buf);
|
DebugDump("%s\n", buf.get());
|
||||||
JS_smprintf_free(buf);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
JS::UniqueChars
|
||||||
xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals,
|
xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals,
|
||||||
bool showThisProps)
|
bool showThisProps)
|
||||||
{
|
{
|
||||||
JS::AutoSaveExceptionState state(cx);
|
JS::AutoSaveExceptionState state(cx);
|
||||||
|
|
||||||
char* buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
JS::UniqueChars buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
DebugDump("%s", "Failed to format JavaScript stack for dump\n");
|
DebugDump("%s", "Failed to format JavaScript stack for dump\n");
|
||||||
|
|
||||||
|
|
|
@ -1009,7 +1009,7 @@ nsXPConnect::DebugPrintJSStack(bool showArgs,
|
||||||
if (!cx)
|
if (!cx)
|
||||||
printf("there is no JSContext on the nsIThreadJSContextStack!\n");
|
printf("there is no JSContext on the nsIThreadJSContextStack!\n");
|
||||||
else
|
else
|
||||||
return xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps);
|
return xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps).release();
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2442,9 +2442,8 @@ extern bool
|
||||||
xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps);
|
xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps);
|
||||||
|
|
||||||
// Return a newly-allocated string containing a representation of the
|
// Return a newly-allocated string containing a representation of the
|
||||||
// current JS stack. It is the *caller's* responsibility to free this
|
// current JS stack.
|
||||||
// string with JS_smprintf_free().
|
extern JS::UniqueChars
|
||||||
extern char*
|
|
||||||
xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals,
|
xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals,
|
||||||
bool showThisProps);
|
bool showThisProps);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче