Tuesday, October 21, 2025

Re: Effect of the omission of the symbolmap files on the stacktrace's line numbers

There is a known issue around chunking that can interfere with stack traces - https://github.com/gwtproject/gwt/issues/9931 - but I don't think that's the whole story of what's happening here (classnames still match the source file they came from, which suggests you aren't seeing it). That issue specifically happens if there are binding properties driving the use of sourcemaps, which means unconditionally enabling sourcemaps functions as a workaround, adding this to late in your .gwt.xml file:

<set-property name="compiler.useSourceMaps" value="true" />

Can you confirm that the three lines of XML only occur in build A and not B? Emulated sourcemaps are great for extremely accurate stack traces, but awful for runtime size and performance. Every line of JS ends up being wrapped in bookkeeping about what file, method, line number is currently being executed - pushing that on a stack, popping it when finished. Expect that to double or triple your output - and it still might have some slight errors/omissions (see below).

Without more information, I don't have anything else to offer about why the stack trace claims SomePanel.java has the error on line 645...

...but from your note at the bottom, some methods will be inlined by the compiler, which can interfere with the stack frames you expect to find. With emulated stack mode, you _could_ get more of that information, but it isn't a given. With native/strip mode, every extra method call added (helpers to make instance methods static that don't always work) or removed (inlined methods that get their contents shifted around and rewritten) can mean that the caller or callee can be lost. Looking at the compiled code might help to match up what changes were made as part of optimizing the app.

(Your email ends on an incomplete sentence, perhaps something was left out?)

On Tuesday, October 21, 2025 at 5:21:45 AM UTC-5 Nick Gaens wrote:
I have witnessed some - imo odd - GWT behavior regarding stacktrace accuracy that I cannot yet fully comprehend, so I am posting it here.

I have a GWT application of which the .gwt.xml file contains these three lines:

<set-property name="compiler.stackMode" value="emulated" />
<set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true"/>
<set-configuration-property name="compiler.emulatedStack.recordFileNames" value="true"/>

Also, I ensured a StringOutOfBoundsException to occur on a distinct screen by doing this:

GWT.log("123".substring(65));

in SomePanel.java on line 195.

To conclude, I made two release builds: 'build A' and 'build B'. A and B are identical, except for B not having any symbol maps present in the resulting file structure (they are manually removed post-compilation) before a distributable zip file is made. The omission of the symbol map files is an attempt to no longer enable end users to be able to view deobfuscated stacktraces directly in the browser's console or to perform deobfuscation manually offline.

When navigating to the broken screen of build A, the stacktrace that is printed to the browser's console is deobfuscated (duh) and - more importantly - 100% correct regarding file names and line numbers. Therefore, it's straightforward to pinpoint where any issue did occur in the original Java code.

When navigating to the broken screen of build B, the stacktrace that is printed to the browser's console is obfuscated, but ... wrong in terms of file names and line numbers... This is the stacktrace that was printed out in the browser's console in this occasion:

java.lang.StringIndexOutOfBoundsException: Index: 65, Size: 4
    at Unknown.qXf(Throwable.java:66)
    at Unknown.CXf(Exception.java:29)
    at Unknown.H3f(RuntimeException.java:29)
    at Unknown.bop(IndexOutOfBoundsException.java:29)
    at Unknown.wrp(StringIndexOutOfBoundsException.java:30)
    at Unknown.OKp(InternalPreconditions.java:487)
    at Unknown.pwf(InternalPreconditions.java:475)
    at Unknown.hbe(NavigationManager.java:287)
    at Unknown.kbe(NavigationManager.java:118)
    at Unknown.RPe(MainPanel.java:604)
    at Unknown.Ung(ValueChangeEvent.java:128)
    at Unknown.hog(GwtEvent.java:76)
    at Unknown._ng(SimpleEventBus.java:88)
    at Unknown.Ntj(History.java:68)
    at Unknown.Vng(ValueChangeEvent.java:43)
    at Unknown.FPe(History.java:77)
    at Unknown.Qae(Application.java:273)
    at Unknown.cbe(Application.java:269)
    at Unknown.wke(TablesDataManager.java:43)
    at Unknown.MWf(JsonRequestBuilder.java:164)
    at Unknown.Pog(Request.java:227)
    at Unknown.cpg(RequestBuilder.java:412)
    at Unknown.anonymous(XMLHttpRequest.java:329)
    at Unknown.Wag(Impl.java:299)
    at Unknown.Zag(Impl.java:351)
    at Unknown.anonymous(Impl.java:78)

Using GWT's com.google.gwt.core.server.StackTraceDeobfuscator and the according symbol map, I was able to deobfuscate this to:

java.lang.Throwable: java.lang.StringIndexOutOfBoundsException: Index: 65, Size: 4
        at java.lang.Throwable.Throwable(Throwable.java:69)
        at java.lang.Exception.Exception(Exception.java:36)
        at java.lang.RuntimeException.RuntimeException(RuntimeException.java:32)
        at java.lang.ArithmeticException.ArithmeticException(ArithmeticException.java:27)
        at java.lang.StringBuilder.StringBuilder(StringBuilder.java:41)
        at javaemul.internal.InternalPreconditions.checkCriticalState(InternalPreconditions.java:379)
        at com.example.client.panels.SomePanel.someMethod(SomePanel.java:645)
        at  com.example.client.NavigationManager.hideAllPopupMenus(NavigationManager.java:372)
        at  com.example.client.NavigationManager.navigateAbsentRequests(NavigationManager.java:457)
        at  com.example.client.panels.main.MainPanel$1.MainPanel$1(MainPanel.java:312)
        at com.google.gwt.event.logical.shared.ValueChangeEvent.ValueChangeEvent(ValueChangeEvent.java:100)
        at com.google.web.bindery.event.shared.SimpleEventBus.$doAddNow(SimpleEventBus.java:168)
        at com.google.gwt.event.shared.HandlerManager.$addHandler(HandlerManager.java:98)
        at com.google.gwt.user.client.History$HistoryEventSource.History$HistoryEventSource(History.java:62)
        at com.google.gwt.event.logical.shared.ValueChangeEvent.dispatch(ValueChangeEvent.java:127)
        at com.example.client.panels.main.MainPanel.$lambda$2(MainPanel.java:252)
        at com.example.client.Application.$successLogin(Application.java:220)
        at com.example.client.Application.$lambda$6$Type.Application$lambda$6$Type(Application.java:299)
        at com.example.client.client.datamanager.SomeDataManager.getSomeData(SomeDataManager.java:100)
        at  com.example.jsonrpc.client.JsonRequestBuilder$2.JsonRequestBuilder$2(JsonRequestBuilder.java:377)
        at com.google.gwt.http.client.Request.$cancel(Request.java:151)
        at com.google.gwt.http.client.RequestBuilder$1.RequestBuilder$1(RequestBuilder.java:408)
        at Unknown.anonymous(XMLHttpRequest.java:329)
        at com.google.gwt.core.client.impl.Impl.enter(Impl.java:313)
        at com.google.gwt.core.client.impl.Impl.exit(Impl.java:373)
        at Unknown.anonymous(Impl.java:78)

So the exception's message is still correct, but the line number where the faulty line of code is present (195) is nowhere to be found in the deobfuscated stacktrace. Also worth noting is that the exception caused by the faulty line of code in SomePanel.java is reached after a few successive method invocations, although the deobfuscated stacktrace doesn't include those in the stack: I expected to have multiple stacktrace elements to exist between the one mentioning SomePanel:someMethod and the one showing the StringIndexOutOfBoundsException happening, but they simply aren't there for some reason.

Can someone shed a light on why all of this is happening in the way it does?

Kind regards,
Nick

When the 

--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/google-web-toolkit/d2872e4b-ca50-4d21-9613-83e6af11dc14n%40googlegroups.com.

No comments:

Post a Comment