зеркало из https://github.com/mozilla/pjs.git
b=403345; dtrace probes get wrong function name, filename, and line number info when native methods are involved; r=brendan
This commit is contained in:
Родитель
3dc9dd5693
Коммит
220c1376a3
|
@ -51,34 +51,41 @@
|
|||
|
||||
static char dempty[] = "<null>";
|
||||
|
||||
char *
|
||||
jsdtrace_funcclass_name(JSFunction *fun)
|
||||
static char *
|
||||
jsdtrace_fun_classname(JSFunction *fun)
|
||||
{
|
||||
return (!FUN_INTERPRETED(fun) &&
|
||||
return (fun &&
|
||||
!FUN_INTERPRETED(fun) &&
|
||||
!(fun->flags & JSFUN_TRACEABLE) &&
|
||||
FUN_CLASP(fun))
|
||||
? (char *)FUN_CLASP(fun)->name
|
||||
: dempty;
|
||||
}
|
||||
|
||||
char *
|
||||
static char *
|
||||
jsdtrace_filename(JSStackFrame *fp)
|
||||
{
|
||||
while (fp && fp->script == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->script && fp->script->filename)
|
||||
? (char *)fp->script->filename
|
||||
: dempty;
|
||||
}
|
||||
|
||||
int
|
||||
jsdtrace_linenumber(JSContext *cx, JSStackFrame *fp)
|
||||
static int
|
||||
jsdtrace_fun_linenumber(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
while (fp && fp->script == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->regs)
|
||||
? (int) js_PCToLineNumber(cx, fp->script, fp->regs->pc)
|
||||
: -1;
|
||||
if (fun && FUN_INTERPRETED(fun))
|
||||
return (int) JS_GetScriptBaseLineNumber(cx, FUN_SCRIPT(fun));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
jsdtrace_frame_linenumber(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
if (fp && fp->regs)
|
||||
return (int) js_FramePCToLineNumber(cx, fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -101,7 +108,7 @@ jsdtrace_linenumber(JSContext *cx, JSStackFrame *fp)
|
|||
* This is used by the function-args and function-rval probes, which also
|
||||
* provide raw (unmasked) jsvals should type info be useful from D scripts.
|
||||
*/
|
||||
void *
|
||||
static void *
|
||||
jsdtrace_jsvaltovoid(JSContext *cx, jsval argval)
|
||||
{
|
||||
JSType type = TYPEOF(cx, argval);
|
||||
|
@ -128,68 +135,23 @@ jsdtrace_jsvaltovoid(JSContext *cx, jsval argval)
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *
|
||||
jsdtrace_function_name(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
static char *
|
||||
jsdtrace_fun_name(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSFrameRegs *regs;
|
||||
JSScript *script;
|
||||
jsbytecode *pc;
|
||||
char *name;
|
||||
|
||||
if (!fun)
|
||||
return dempty;
|
||||
|
||||
atom = fun->atom;
|
||||
if (!atom) {
|
||||
if (fp->fun != fun || !fp->down)
|
||||
return dempty;
|
||||
|
||||
regs = fp->down->regs;
|
||||
if (!regs)
|
||||
return dempty;
|
||||
|
||||
/*
|
||||
* An anonymous function called from an active script or interpreted
|
||||
* function: try to fetch the variable or property name by which the
|
||||
* anonymous function was invoked.
|
||||
* TODO: maybe do more work here to figure out the name of the property
|
||||
* or variable that held the anonymous function that we're calling, if anyone
|
||||
* cares; an easy workaround is to just give your anonymous functions names.
|
||||
*/
|
||||
pc = regs->pc;
|
||||
script = fp->down->script;
|
||||
switch ((JSOp) *pc) {
|
||||
case JSOP_CALL:
|
||||
case JSOP_EVAL:
|
||||
JS_ASSERT(fp->argv == regs->sp - (int)GET_ARGC(pc));
|
||||
|
||||
/*
|
||||
* FIXME bug 422864: update this code to use the pc stack from the
|
||||
* decompiler.
|
||||
*/
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
|
||||
switch ((JSOp) *pc) {
|
||||
case JSOP_CALLNAME:
|
||||
case JSOP_CALLPROP:
|
||||
case JSOP_NAME:
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_GETPROP:
|
||||
case JSOP_SETPROP:
|
||||
GET_ATOM_FROM_BYTECODE(script, pc, 0, atom);
|
||||
break;
|
||||
|
||||
case JSOP_CALLELEM:
|
||||
case JSOP_GETELEM:
|
||||
case JSOP_SETELEM:
|
||||
case JSOP_CALLGVAR:
|
||||
case JSOP_GETGVAR:
|
||||
case JSOP_SETGVAR:
|
||||
case JSOP_CALLARG:
|
||||
case JSOP_CALLLOCAL:
|
||||
/* FIXME: try to recover a name from these ops. */
|
||||
/* FALL THROUGH */
|
||||
|
||||
default:
|
||||
return dempty;
|
||||
}
|
||||
return dempty;
|
||||
}
|
||||
|
||||
name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom));
|
||||
|
@ -208,8 +170,8 @@ jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
|||
{
|
||||
JAVASCRIPT_FUNCTION_ENTRY(
|
||||
jsdtrace_filename(fp),
|
||||
jsdtrace_funcclass_name(fun),
|
||||
jsdtrace_function_name(cx, fp, fun)
|
||||
jsdtrace_fun_classname(fun),
|
||||
jsdtrace_fun_name(cx, fun)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -219,39 +181,40 @@ jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
|
|||
{
|
||||
JAVASCRIPT_FUNCTION_INFO(
|
||||
jsdtrace_filename(fp),
|
||||
jsdtrace_funcclass_name(fun),
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
fp->script->lineno,
|
||||
jsdtrace_fun_classname(fun),
|
||||
jsdtrace_fun_name(cx, fun),
|
||||
jsdtrace_fun_linenumber(cx, fun),
|
||||
jsdtrace_filename(dfp),
|
||||
jsdtrace_linenumber(cx, dfp)
|
||||
jsdtrace_frame_linenumber(cx, dfp)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsuint argc, jsval *argv)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_ARGS(
|
||||
jsdtrace_filename(fp),
|
||||
jsdtrace_funcclass_name(fun),
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
fp->argc, (void *)fp->argv,
|
||||
(fp->argc > 0) ? jsdtrace_jsvaltovoid(cx, fp->argv[0]) : 0,
|
||||
(fp->argc > 1) ? jsdtrace_jsvaltovoid(cx, fp->argv[1]) : 0,
|
||||
(fp->argc > 2) ? jsdtrace_jsvaltovoid(cx, fp->argv[2]) : 0,
|
||||
(fp->argc > 3) ? jsdtrace_jsvaltovoid(cx, fp->argv[3]) : 0,
|
||||
(fp->argc > 4) ? jsdtrace_jsvaltovoid(cx, fp->argv[4]) : 0
|
||||
jsdtrace_fun_classname(fun),
|
||||
jsdtrace_fun_name(cx, fun),
|
||||
argc, (void *)argv,
|
||||
(argc > 0) ? jsdtrace_jsvaltovoid(cx, argv[0]) : 0,
|
||||
(argc > 1) ? jsdtrace_jsvaltovoid(cx, argv[1]) : 0,
|
||||
(argc > 2) ? jsdtrace_jsvaltovoid(cx, argv[2]) : 0,
|
||||
(argc > 3) ? jsdtrace_jsvaltovoid(cx, argv[3]) : 0,
|
||||
(argc > 4) ? jsdtrace_jsvaltovoid(cx, argv[4]) : 0
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval *rval)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_RVAL(
|
||||
jsdtrace_filename(fp),
|
||||
jsdtrace_funcclass_name(fun),
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
jsdtrace_linenumber(cx, fp), (void *)fp->rval,
|
||||
jsdtrace_jsvaltovoid(cx, fp->rval)
|
||||
jsdtrace_fun_classname(fun),
|
||||
jsdtrace_fun_name(cx, fun),
|
||||
jsdtrace_fun_linenumber(cx, fun),
|
||||
(void *)rval,
|
||||
jsdtrace_jsvaltovoid(cx, *rval)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -260,8 +223,8 @@ jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
|||
{
|
||||
JAVASCRIPT_FUNCTION_RETURN(
|
||||
jsdtrace_filename(fp),
|
||||
jsdtrace_funcclass_name(fun),
|
||||
jsdtrace_function_name(cx, fp, fun)
|
||||
jsdtrace_fun_classname(fun),
|
||||
jsdtrace_fun_name(cx, fun)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -284,7 +247,7 @@ jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj)
|
|||
jsdtrace_filename(cx->fp),
|
||||
(char *)clasp->name,
|
||||
(uintptr_t)obj,
|
||||
jsdtrace_linenumber(cx, cx->fp)
|
||||
jsdtrace_frame_linenumber(cx, cx->fp)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,10 +50,10 @@ jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
|
|||
JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsuint argc, jsval *argv);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval *rval);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
|
|
|
@ -1367,6 +1367,16 @@ have_fun:
|
|||
if (hook)
|
||||
hookData = hook(cx, &frame, JS_TRUE, 0, cx->debugHooks->callHookData);
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function entry, non-inlines */
|
||||
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
|
||||
jsdtrace_function_entry(cx, &frame, fun);
|
||||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, &frame, frame.down, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, &frame, fun, frame.argc, frame.argv);
|
||||
#endif
|
||||
|
||||
/* Call the function, either a native method or an interpreted script. */
|
||||
if (native) {
|
||||
#ifdef DEBUG_NOT_THROWING
|
||||
|
@ -1388,6 +1398,14 @@ have_fun:
|
|||
ok = js_Interpret(cx);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function return, non-inlines */
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, &frame, fun, &frame.rval);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, &frame, fun);
|
||||
#endif
|
||||
|
||||
out:
|
||||
if (hookData) {
|
||||
hook = cx->debugHooks->callHook;
|
||||
|
@ -3264,7 +3282,7 @@ js_Interpret(JSContext *cx)
|
|||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function return, inlines */
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fp->fun);
|
||||
jsdtrace_function_rval(cx, fp, fp->fun, &fp->rval);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fp->fun);
|
||||
#endif
|
||||
|
@ -5143,7 +5161,7 @@ js_Interpret(JSContext *cx)
|
|||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, fp, fp->down, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, fp, fun);
|
||||
jsdtrace_function_args(cx, fp, fun, fp->argc, fp->argv);
|
||||
#endif
|
||||
|
||||
/* Load first op and dispatch it (safe since JSOP_STOP). */
|
||||
|
@ -5158,19 +5176,19 @@ js_Interpret(JSContext *cx)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (fun->flags & JSFUN_FAST_NATIVE) {
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function entry, non-inlines */
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
|
||||
jsdtrace_function_entry(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, fp, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, fp, fun);
|
||||
}
|
||||
/* DTrace function entry, non-inlines */
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
|
||||
jsdtrace_function_entry(cx, NULL, fun);
|
||||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, NULL, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, fp, fun, argc, vp+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fun->flags & JSFUN_FAST_NATIVE) {
|
||||
JS_ASSERT(fun->u.n.extra == 0);
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(vp[1]) ||
|
||||
PRIMITIVE_THIS_TEST(fun, vp[1]));
|
||||
|
@ -5178,9 +5196,9 @@ js_Interpret(JSContext *cx)
|
|||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fun);
|
||||
jsdtrace_function_rval(cx, NULL, fun, vp);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fun);
|
||||
jsdtrace_function_return(cx, NULL, fun);
|
||||
}
|
||||
#endif
|
||||
regs.sp = vp + 1;
|
||||
|
@ -5207,15 +5225,6 @@ js_Interpret(JSContext *cx)
|
|||
}
|
||||
|
||||
ok = js_Invoke(cx, argc, vp, 0);
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function return, non-inlines */
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fun);
|
||||
}
|
||||
#endif
|
||||
regs.sp = vp + 1;
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
if (!ok)
|
||||
|
|
Загрузка…
Ссылка в новой задаче