Print JS stack trace when reporting exceptions.

Increase maximum logger message size.
Fix GC bug.

This was SVN commit r8063.
This commit is contained in:
Ykkrosh 2010-09-03 20:06:17 +00:00
parent 5cc04d44f8
commit 5e15a0279e
4 changed files with 39 additions and 7 deletions

View file

@ -129,7 +129,10 @@ template<> jsval ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, SDL_Event_
}
}
return OBJECT_TO_JSVAL(obj);
jsval rval = OBJECT_TO_JSVAL(obj);
scope.LeaveWithResult(rval);
return rval;
}
template<> jsval ScriptInterface::ToJSVal<IGUIObject*>(JSContext* UNUSED(cx), IGUIObject* const& val)

View file

@ -42,6 +42,8 @@ static const double RENDER_TIMEOUT = 10.0; // seconds before messages are delete
static const double RENDER_TIMEOUT_RATE = 10.0; // number of timed-out messages deleted per second
static const size_t RENDER_LIMIT = 20; // maximum messages on screen at once
static const size_t BUFFER_SIZE = 1024;
extern int g_xres, g_yres;
// Set up a default logger that throws everything away, because that's
@ -215,7 +217,7 @@ void CLogger::LogUsingMethod(ELogMethod method, const wchar_t* message)
void CLogger::Log(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...)
{
va_list argp;
wchar_t buffer[512] = {0};
wchar_t buffer[BUFFER_SIZE] = {0};
va_start(argp, fmt);
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
@ -232,7 +234,7 @@ void CLogger::Log(ELogMethod method, const wchar_t* UNUSED(category), const wcha
void CLogger::LogOnce(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...)
{
va_list argp;
wchar_t buffer[512] = {0};
wchar_t buffer[BUFFER_SIZE] = {0};
va_start(argp, fmt);
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
@ -256,7 +258,7 @@ void CLogger::LogOnce(ELogMethod method, const wchar_t* UNUSED(category), const
void CLogger::LogMessage(const wchar_t* fmt, ...)
{
va_list argp;
wchar_t buffer[512] = {0};
wchar_t buffer[BUFFER_SIZE] = {0};
va_start(argp, fmt);
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
@ -272,7 +274,7 @@ void CLogger::LogMessage(const wchar_t* fmt, ...)
void CLogger::LogWarning(const wchar_t* fmt, ...)
{
va_list argp;
wchar_t buffer[512] = {0};
wchar_t buffer[BUFFER_SIZE] = {0};
va_start(argp, fmt);
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
@ -288,7 +290,7 @@ void CLogger::LogWarning(const wchar_t* fmt, ...)
void CLogger::LogError(const wchar_t* fmt, ...)
{
va_list argp;
wchar_t buffer[512] = {0};
wchar_t buffer[BUFFER_SIZE] = {0};
va_start(argp, fmt);
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)

View file

@ -76,7 +76,7 @@ JSClass global_class = {
NULL, NULL, NULL, NULL
};
void ErrorReporter(JSContext* UNUSED(cx), const char* message, JSErrorReport* report)
void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
{
// XXX Ugly hack: we want to compile code with 'use strict' and with JSOPTION_STRICT,
// but the latter causes the former to be reported as a useless expression, so
@ -92,11 +92,28 @@ void ErrorReporter(JSContext* UNUSED(cx), const char* message, JSErrorReport* re
msg << report->filename;
msg << " line " << report->lineno << "\n";
}
msg << message;
// If there is an exception, then print its stack trace
jsval excn;
if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
{
jsval rval;
const char dumpStack[] = "this.stack.trimRight().replace(/^/mg, ' ')"; // indent each line
if (JS_EvaluateScript(cx, JSVAL_TO_OBJECT(excn), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, &rval))
{
std::string stackTrace;
if (ScriptInterface::FromJSVal(cx, rval, stackTrace))
msg << "\n" << stackTrace;
}
}
if (isWarning)
LOGWARNING(L"%hs", msg.str().c_str());
else
LOGERROR(L"%hs", msg.str().c_str());
// When running under Valgrind, print more information in the error message
VALGRIND_PRINTF_BACKTRACE("->");
}
@ -400,6 +417,14 @@ bool ScriptInterface::LocalRootScope::OK()
return m_OK;
}
void ScriptInterface::LocalRootScope::LeaveWithResult(jsval val)
{
if (m_OK)
JS_LeaveLocalRootScopeWithResult(m_cx, val);
m_OK = false;
}
jsval ScriptInterface::CallConstructor(jsval ctor)
{
// Constructing JS objects similarly to "new Foo" is non-trivial.

View file

@ -221,6 +221,8 @@ public:
LocalRootScope(JSContext* cx);
// Returns true if the local root scope was successfully entered
bool OK();
// Leaves the local root scope, but keeps the given return value rooted
void LeaveWithResult(jsval val);
// Leaves the local root scope
~LocalRootScope();
private: