1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/src/XPCDebug.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,134 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "xpcprivate.h" 1.11 +#include "jsprf.h" 1.12 +#include "js/OldDebugAPI.h" 1.13 + 1.14 +#ifdef XP_WIN 1.15 +#include <windows.h> 1.16 +#endif 1.17 + 1.18 +static void DebugDump(const char* fmt, ...) 1.19 +{ 1.20 + char buffer[2048]; 1.21 + va_list ap; 1.22 + va_start(ap, fmt); 1.23 +#ifdef XPWIN 1.24 + _vsnprintf(buffer, sizeof(buffer), fmt, ap); 1.25 +#else 1.26 + vsnprintf(buffer, sizeof(buffer), fmt, ap); 1.27 +#endif 1.28 + buffer[sizeof(buffer)-1] = '\0'; 1.29 + va_end(ap); 1.30 +#ifdef XP_WIN 1.31 + if (IsDebuggerPresent()) { 1.32 + OutputDebugStringA(buffer); 1.33 + } 1.34 +#endif 1.35 + printf("%s", buffer); 1.36 +} 1.37 + 1.38 +bool 1.39 +xpc_DumpJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps) 1.40 +{ 1.41 + if (char* buf = xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps)) { 1.42 + DebugDump("%s\n", buf); 1.43 + JS_smprintf_free(buf); 1.44 + } 1.45 + return true; 1.46 +} 1.47 + 1.48 +char* 1.49 +xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, 1.50 + bool showThisProps) 1.51 +{ 1.52 + JS::AutoSaveExceptionState state(cx); 1.53 + 1.54 + char *buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps); 1.55 + if (!buf) 1.56 + DebugDump("%s", "Failed to format JavaScript stack for dump\n"); 1.57 + 1.58 + state.restore(); 1.59 + return buf; 1.60 +} 1.61 + 1.62 +/***************************************************************************/ 1.63 + 1.64 +static void 1.65 +xpcDumpEvalErrorReporter(JSContext *cx, const char *message, 1.66 + JSErrorReport *report) 1.67 +{ 1.68 + DebugDump("Error: %s\n", message); 1.69 +} 1.70 + 1.71 +bool 1.72 +xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text) 1.73 +{ 1.74 + if (!cx || !text) { 1.75 + DebugDump("%s", "invalid params passed to xpc_DumpEvalInJSStackFrame!\n"); 1.76 + return false; 1.77 + } 1.78 + 1.79 + DebugDump("js[%d]> %s\n", frameno, text); 1.80 + 1.81 + uint32_t num = 0; 1.82 + 1.83 + JSAbstractFramePtr frame = JSNullFramePtr(); 1.84 + 1.85 + JSBrokenFrameIterator iter(cx); 1.86 + while (!iter.done()) { 1.87 + if (num == frameno) { 1.88 + frame = iter.abstractFramePtr(); 1.89 + break; 1.90 + } 1.91 + ++iter; 1.92 + num++; 1.93 + } 1.94 + 1.95 + if (!frame) { 1.96 + DebugDump("%s", "invalid frame number!\n"); 1.97 + return false; 1.98 + } 1.99 + 1.100 + JS::AutoSaveExceptionState exceptionState(cx); 1.101 + JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter); 1.102 + 1.103 + JS::RootedValue rval(cx); 1.104 + JSString* str; 1.105 + JSAutoByteString bytes; 1.106 + if (frame.evaluateInStackFrame(cx, text, strlen(text), "eval", 1, &rval) && 1.107 + nullptr != (str = ToString(cx, rval)) && 1.108 + bytes.encodeLatin1(cx, str)) { 1.109 + DebugDump("%s\n", bytes.ptr()); 1.110 + } else { 1.111 + DebugDump("%s", "eval failed!\n"); 1.112 + } 1.113 + 1.114 + JS_SetErrorReporter(cx, older); 1.115 + exceptionState.restore(); 1.116 + return true; 1.117 +} 1.118 + 1.119 +/***************************************************************************/ 1.120 + 1.121 +JSTrapStatus 1.122 +xpc_DebuggerKeywordHandler(JSContext *cx, JSScript *script, jsbytecode *pc, 1.123 + jsval *rval, void *closure) 1.124 +{ 1.125 + static const char line[] = 1.126 + "------------------------------------------------------------------------\n"; 1.127 + DebugDump("%s", line); 1.128 + DebugDump("%s", "Hit JavaScript \"debugger\" keyword. JS call stack...\n"); 1.129 + xpc_DumpJSStack(cx, true, true, false); 1.130 + DebugDump("%s", line); 1.131 + return JSTRAP_CONTINUE; 1.132 +} 1.133 + 1.134 +bool xpc_InstallJSDebuggerKeywordHandler(JSRuntime* rt) 1.135 +{ 1.136 + return JS_SetDebuggerHandler(rt, xpc_DebuggerKeywordHandler, nullptr); 1.137 +}