Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackTraceDeobfuscator sometimes produces total nonsense #9931

Open
jnehlmeier opened this issue Feb 26, 2024 · 5 comments
Open

StackTraceDeobfuscator sometimes produces total nonsense #9931

jnehlmeier opened this issue Feb 26, 2024 · 5 comments

Comments

@jnehlmeier
Copy link
Member

GWT version: head


Description

Once the application is large enough I think a hidden bug in GWTs symbol maps / source maps appears more and more often. It results in deobfuscated stack traces with incorrect file and line numbers.

Consider the following example:

at java.lang.Throwable.Throwable(com/google/common/base/MoreObjects.java:437)
	at java.lang.RuntimeException.RuntimeException(com/google/common/base/Preconditions.java:1422)
	at com.google.web.bindery.event.shared.UmbrellaException.UmbrellaException(UmbrellaException.java:142)
	at com.google.gwt.event.shared.UmbrellaException.UmbrellaException(com/google/common/base/Splitter.java:424)
	at com.google.gwt.user.client.ui.AttachDetachException.AttachDetachException(com/google/common/collect/RegularImmutableAsList.java:44)
	at com.google.gwt.user.client.ui.AttachDetachException.tryCommand(com/google/common/collect/RegularImmutableAsList.java:34)
	at com.google.gwt.user.client.ui.Panel.doDetachChildren(Panel.java:108)
	at com.google.gwt.user.client.ui.Widget.$onDetach(com/google/common/base/Joiner.java:276)
	at com.google.gwt.user.client.ui.Widget.onDetach(Widget.java:108)
	at com.google.gwt.user.client.ui.Composite.$onDetach(com/google/common/collect/Iterators.java:1433)
	at com.google.gwt.user.client.ui.Composite.onDetach(Composite.java:225)
	at com.google.gwt.user.client.ui.AttachDetachException$2.execute(AttachDetachException.java:249)
	at com.google.gwt.user.client.ui.AttachDetachException.tryCommand(com/google/common/collect/RegularImmutableAsList.java:48)

For some reason it often contains Guava classes as files for GWT classes but it can also contain other wrong files from the application itself or GWT SDK.

Steps to reproduce

Difficult to reproduce in an example project

Known workarounds

None

@niloc132
Copy link
Contributor

We're actually looking at updating the sourcemap implementation right now for other benefits (slightly faster linking, fewer tiny files on disk, and drop the mostly-unneeded old protobuf dependency in gwt-servlet), and can take a look at this at the same time if there is some way to reproduce this, or at least broken symbolMap/sourcemap files to work from? Those files plus the frame info (obf method name, file name, line and column numbers) should make it possible to see where the mismatch is, and hopefully reproduce and fix it.

I've never dug too deeply on this part, but it looks like the symbolmap is first used to rewrite from the obfuscated/generated js method name, then augment with sourcemaps. If I'm reading this right, the fact that you see qualified paths (com/google/common/base/Joiner.java etc) rather than just the bare file name (Widget.java or Joiner.java) suggests that you're not just getting the symbolmap data, as that reads after the last index of / in the uri:

if (fileName == null || !fileName.endsWith(".java")) {
// parts[3] contains the source file URI or "Unknown"
fileName = "Unknown".equals(parts[3]) ? null
: parts[3].substring(parts[3].lastIndexOf('/') + 1);
}

Instead, the bad path seems to be coming from sourcemaps. Any chance you're customizing the linker in any way, which might alter the offsets...?

@jnehlmeier
Copy link
Member Author

Sadly I cannot share the code or symbolMap/sourcemap. It is also pretty large since a permutation is about 10MB. The above example was produced on iOS. I could try checking if it is always iOS/webkit or if other browsers also have the problem and if it is always using a qualified path if the filename is wrong.

At least I can say that no custom linker is used, just the default one of GWT.

First I thought it could be JsInliner but then some really wild combinations occurred, like the one above, that cannot be explained with inlining. It looks like a more fundamental problem either in GWT or in the app.

@niloc132
Copy link
Contributor

We don't need the full thing to analyze, see what might be wrong, just enough to accurately point the finger? Otherwise we're pretty limited to finding someone else who can share some files.

In theory, just the stack trace (with all the details, like the one you shared above except pre-deobfuscation), the relevant symbolmap lines (again, only maps to com.google.common and com.google.gwt classes and methods)... and the sourcemap info. That is a bit harder to decompose, but at least if you confirm the first two, you will know that symbolmaps are probably not to blame, and that we're looking at a sourcemap issue of some kind.

They certainly can be decomposed though - the java api in sourcemap-rebased.jar isn't too terrible to walk if you want to do it yourself. Alternatively, as I said in my other comment, we'll be updating that jar soon, and maybe the issue will resolve itself from some change to closure-compiler in the last ~8 years...

@niloc132
Copy link
Contributor

Any actual details you can share on this? Otherwise, consider pulling from #9936 (and leaving compiler.embedSourceMaps to false, since you aren't interested in that).

Also just in case, you don't think this is a dup of #9038? I'm assuming that you checked, but maybe you missed that one? Just in case, that would seem to add a constant offset somewhere in your stack, which could produce what you're seeing (but you could only confirm with access to the compiled JS). At a brief glance, that should only happen if you happen to be generating prod code as non-OBFUSCATED.

Given that only frames that are correct are those with no sourcemap details added, it seems plausible that this is the same issue? Can you confirm other compiler settings, etc, so we can hunt this down while we're working on sourcemaps?

@jnehlmeier
Copy link
Member Author

Not really. Poking around takes too long at work since compiling the app is about 10-15 minutes and I actually forgot to check the issue tracker if only specific browsers are affected. I am basically waiting for an exception that can easily be reproduced and has a broken stack trace. Then I can checkout the source of that production build, modify the server and log both JS and deobfuscated stack traces using various browsers.

I can't remember how it works but I think I have never seen a broken stack trace during development using Chrome + SDM. In development exceptions are directly logged to browser console.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants