Stacktraces from dynamically-constructed functions not as expected
Vivin Suresh Paliath
vivin.paliath at gmail.com
Fri May 13 05:21:13 UTC 2016
I have the same preference! That is exactly why I name functions even when
they are function expressions. I am developing an API where having the name
of the function in the stack trace would be a useful debugging aid as well.
Yes the f$foo vs. foo is a different issue, but I would also prefer that
foo is shown regardless. I noticed that I was able to replicate the
behavior of the second case if I removed the "var f =" and immediately
invoked the result of the IIFE.
Since I am on jdk8u92 I checked out the 8u-dev branch and stepped through
the parser (by the way, is it possible to check out the Nashorn source for
8u92? I only saw a 8u92-b14 tag). I noticed that it does create an
IdentNode with "foo", and then uses that to create a FunctionNode instance.
I am not sure how the function still ends up as anonymous but I am planning
to look at it in some more detail tomorrow.
On May 12, 2016 8:12 PM, "Sundararajan Athijegannathan" <
sundararajan.athijegannathan at oracle.com> wrote:
Adding to what Hannes said: "stack" property and the format of stack
trace are not part of ECMAScript standard. Implementations could
differ in this. This is more of debugging aid as Hannes mentioned.
I'd personally prefer names being shown in stack traces whenever
possible - rather than <anonymous> being shown!
The fact that user chose to name an "anonymous" function => s/he prefers
to name the function expression in question. Purpose? Most likely
debugging/code-search aid. So, I'd rather like that name be shown in
some form. [whether to show source name "foo" for "f$foo" is another
question. But "foo" being included in some form].
That said, if there is any ECMAScript standard specified API that is
broken because of this choice by nashorn, we should attempt to fix that.
Thanks,
-Sundar
On 5/13/2016 2:42 AM, Hannes Wallnoefer wrote:
> 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