Error Stack Column number

Art Fiedler artfiedler at gmail.com
Fri Dec 2 21:23:46 UTC 2016


I had a few thoughts on this but after evaluating it wouldn't work out...

If it were possible to modify java.lang.Throwable & StackTraceElement I had
thought to do some bit shifting to combine line & column numbers into a
negative number and place that as the line number value stored in the
LineNumberTable attribute, then converting the linenumber into line/column
in StackTraceElement. However it seems that the datatype is 2bytes only
creating a huge limitation on the size of script. Then I had thought well
maybe store the offset position as a negative number and provide a map to
get line & column... but again 2bytes isn't enough to store an offset,
less.min.js's character count is 152,193. So even if such a modification
was allowed it would not be very useful.

The other idea to push/pop on a threadlocal would I think also require a
try/finally on every method call... which I'm guessing would be a large
performance hit. In this case I would think the column number would only be
included if the error was caught in nashorn so it can populate the column
numbers on the stack... that would solve my case but it wouldn't be
consistent when caught externally.

-Arthur Fiedler

On Fri, Dec 2, 2016 at 5:25 AM, Sundararajan Athijegannathan <
sundararajan.athijegannathan at oracle.com> wrote:

> Note that nashorn always compiles to bytecode - no parallel side data
> structure for JS stacks or "interpreter stack" here.
>
> That said (if this can be done without hurting performance) we'd be
> happy to accept contributions.
>
> -Sundar
>
>
> On 12/2/2016 4:34 PM, Art Fiedler wrote:
> > Without knowing all the internals of nashorn. I don't know if an internal
> > calling tree exists or how complicated it would be to build, but it seems
> > the runtime could track function calls and maintain its own stack.
> >
> > CallNode before code is generated has the token/linenumber where it came
> > from, store a unique id of the callnode, with filename, line, column, in
> > the runtime. Then as a call node is executed push to the call stack the
> id
> > of the call node, and pop when call is complete... when the stack is
> > requested capture the current threads callnode id list (maybe use a
> thread
> > local?) match it up with the stored callnode id info map...
> merge/overwrite
> > stackelements in the stack trace gathered from Throwable.
> >
> > Well, that's what just rolled off my head of how it could possibly be
> done.
> >
> > -Arthur Fiedler
> >
> > On Fri, Dec 2, 2016 at 4:09 AM, Sundararajan Athijegannathan <
> > sundararajan.athijegannathan at oracle.com> wrote:
> >
> >> StackTraceElement being final is not the only issue here. How do to pass
> >> around & populate column numbers for the script frames?  That is the
> >> main issue here..
> >>
> >> -Sundar
> >>
> >> On 12/2/2016 3:00 PM, Art Fiedler wrote:
> >>> Yeah I almost mentioned that StackTraceElement doesn't provide a column
> >>> number to populate but removed that comment, thinking "well,
> >>> StackTraceElement could just be extended for NashornStackTraceElement",
> >> but
> >>> now looking at it I notice it's final. ugh. But it doesn't technically
> >> mean
> >>> an array of StackTraceElement's cant be converted to
> >>> NashornStackTraceElement's after getting the stack from the jvm, then
> >>> matching up script frames and populating additional information.
> >>>
> >>> -Arthur Fiedler
> >>>
> >>> On Fri, Dec 2, 2016 at 2:59 AM, Sundararajan Athijegannathan <
> >>> sundararajan.athijegannathan at oracle.com> wrote:
> >>>
> >>>> Error has columnNumber property - but as you've noted it is not always
> >>>> available :(  If the error is thrown from script code anywhere via
> >>>> ECMAScript throw statement, we do populate column number - because
> >>>> nashorn could compile the code appropriately to put column number!
> >>>>
> >>>> But, there are places in nashorn runtime code where ECMAScript errors
> >>>> are thrown. For example, RangeError thrown from deep inside nashorn
> >>>> runtime Java code! From those places, we can only recover java stack
> >>>> trace & populate properties of ECMA error object.  As java
> >>>> StackTraceElement objects do not have column number, we can't populate
> >>>> column number.
> >>>>
> >>>> -Sundar
> >>>>
> >>>> On 12/2/2016 2:06 PM, Art Fiedler wrote:
> >>>>> Your right it's still not standard even in the EMCAScript 2016, it
> just
> >>>>> seems to
> >>>>> be the commonality. When thinking java yes line only makes sense as
> >>>>> typically
> >>>>> one who writes java does not minify the code. When thinking
> javascript
> >>>>> however
> >>>>> minified code is quite normal and myfile:1 might mean 5000 other
> lines
> >> as
> >>>>> well.
> >>>>>
> >>>>> I looked into the source some to see if it actually is feasible to
> >> build
> >>>> my
> >>>>> own
> >>>>> stacktrace with file:line:column, however in the current state it
> seems
> >>>>> impossible! Nashorn actually uses java.lang.Throwable.
> getStackTrace()
> >> to
> >>>>> get the
> >>>>> stack and that ends up being native. The only place you can get the
> >>>>> columnNumber
> >>>>> is for the specific location the error was thrown. Keyword "thrown".
> >>>>>
> >>>>> If you noticed my previous sample new Error().columnNumber === -1
> since
> >>>>> columnNumber is not populated... however if you throw & catch then...
> >>>>>     try { throw new Error(); }
> >>>>>     catch(e) { /* e.columnNumber === 6 */ }
> >>>>>
> >>>>> In my case with console.count(), the need for columnNumber is not the
> >>>>> location
> >>>>> of new Error() either, since the console.count() function would need
> >> the
> >>>>> callers file:line:col as that is where console.count() is called
> from.
> >>>>>
> >>>>> In the end I still think if the stack element is from a script it
> >> should
> >>>>> include
> >>>>> the column number like node.js, ff, edge all seem to be doing. Since
> a
> >>>> line
> >>>>> only
> >>>>> is useless when the script is minified. However considering that
> >> nashorn
> >>>> is
> >>>>> not
> >>>>> providing the stackTrace directly, I could see why the team may not
> >> want
> >>>> to
> >>>>> include the columnNumber. If you do however know of another way to
> get
> >>>> the
> >>>>> callers file:line:col please let me know. My second thought was to
> >> check
> >>>>> arguments.callee.caller for that info but no dice.
> >>>>>
> >>>>> -Arthur Fiedler
> >>>>>
> >>>>> We do not aim to provide complete compatibility with other JS
> >>>>>> implementations on the non-standard properties such as "stack".
> stack
> >>>>>> tries to mimic whatever is done for Java code (no column number for
> >>>>>> eg.). But, as you've noted there are enough information on Error
> >> objects
> >>>>>> via other properties like lineNumber, columnNumber, fileName. It
> >> should
> >>>>>> be possible to write a simple utility function to format stack
> string
> >> as
> >>>>>> desired for specific applications.
> >>>>>>
> >>>>>> Thanks,
> >>>>>> -Sundar
> >>>>>>
> >>
>
>


More information about the nashorn-dev mailing list