Stacktraces from dynamically-constructed functions not as expected
Hannes Wallnoefer
hannes.wallnoefer at oracle.com
Thu May 12 21:12:15 UTC 2016
Hi Vivin,
What you see is some fuzziness in the translation from JS functions to
Java methods and from there to the stack traces you see.
When we compile a JS function, we create a Java method with the name of
the function concatenated to the names of its parent functions, using
'$' as separator. For anonymous functions we use something like L:123 as
name where 123 is the line of code where the function begins.
This method naming scheme helps a lot in making bytecode easier to
debug, and to create unique method names within a compilation unit.
However, it also leads to the stack traces you see, getting f$foo in the
first case and something like L1:foo in the second case, which is
rendered as <anonymous> in the stack trace.
Ideally we should reverse this when printing stack traces, displaying
only the name of the function itself, e.g. "bar" for "foo$bar" and
"<anonymous>" for "foo$L:3". Unfortunately, "$" is a valid character in
a JS identifier, so it's not that easy, "foo$bar" may also be the name
of the original function.
I'm thinking about how to solve this and will probably file an issue for it.
Hannes
Am 2016-05-12 um 15:59 schrieb Vivin Suresh Paliath:
> I tried this out on in chrome and I get the expected stack trace there. Is
> this a bug?
> On May 6, 2016 3:39 PM, "Vivin Suresh Paliath" <vivin.paliath at gmail.com>
> wrote:
>
>> I have the following code:
>>
>> *var f = (function() {*
>> * return function foo() {*
>> * try {*
>> * throw new Error();*
>> * } catch(e) {*
>> * print(e.stack);*
>> * }*
>> * }*
>> *})();*
>>
>>
>> When I call the function, I get the following stacktrace as expected
>> (mostly; I was expecting *foo* instead of *f$foo*).
>>
>> *Error*
>> * at f$foo (<shell>:1)*
>> * at <program> (<shell>:1)*
>>
>>
>> However, if I dynamically construct the function as follows:
>>
>> *var f = new Function([], "return function foo() { try { throw new
>> Error(); } catch(e) { print(e.stack); } }")()*
>>
>>
>> I get:
>>
>>
>> *Error*
>> * at <anonymous> (<function>:2)*
>> * at <program> (<shell>:1)*
>>
>>
>> Is there a reason for this discrepancy? Isn't the second version
>> effectively the same as the first? Also, why is it *f$foo* instead of
>> *foo* in the first case?
>>
>> I am running jdk8u92.
>>
>> Thanks!
>>
>> --
>> Ruin untold;
>> And thine own sadness,
>> Sing in the grass,
>> When eve has forgot, that no more hear common things that gleam and pass;
>> But seek alone to lip, sad Rose of love and ruin untold;
>> And thine own mother
>> Can know it as I know
>> More than another
>> What makes your own sadness,
>> Set in her eyes.
>>
>> map{@n=split//;$j.=$n[0]x$n[1]}split/:/,"01:11:02".
>> ":11:01:11:02:13:01:11:01:11:01:13:02:12:01:13:01".
>> ":11:04:11:06:12:04:11:01:12:01:13:02:12:01:14:01".
>> ":13:01:11:03:12:01:11:04:12:02:11:01:11:01:13:02".
>> ":11:03:11:06:11:01:11:05:12:02:11:01:11:01:13:02".
>> ":11:02:12:01:12:04:11:06:12:01:11:04:12:04:11:01".
>> ":12:03:12:01:12:01:11:01:12:01:12:02:11:01:11:01".
>> ":13:02:11:01:02:11:01:12:02";map{print chr unpack"
>> i",pack"B32",$_}$j=~m/.{8}/g
>>
More information about the nashorn-dev
mailing list