Open kamilogorek opened 1 year ago
cc @Swatinem @loewenheim @marandaneto for visibility.
@kamilogorek we can look at their own symbolicator source code:
source_map_stack_trace source_maps stack_trace native_stack_traces
But let's wait for the Dart team to follow up since we already have a workaround.
Thanks for reaching out!
I'm curious to learn more about what does your symbolication service provides and whether it matches how we produce source-maps.
Our encoding of source-map was tailored for two use cases: local debugging and deobfuscation of production stack traces. Years ago we had a lot of symbol information that was never in use and we started noticing the tax (e.g. memory utilization on deobfuscation servers). As a result, today we use a frugal approach and only include symbol information if it supports known scenarios.
debugging: our goal was to include data to assist debugging on modern browsers with source maps. For this we tracked down precisely where browsers allow you to set breakpoints, and ensure those positions had a source-mapping associated with it. Debuggers were not using the original name almost entirely, so this use case didn't require that we add much in terms of original names.
deobfuscation: our goal was to add data to deobfuscate error messages and stack traces produced in production. Here we do use a lot of symbol information. That said, standard source-maps were not sufficient. We designed custom extensions to fill the gap. This includes:
We hope that one day source-maps will consider incorporating some of these extensions in the future into the standard, but that will take time. This is being tracked in https://github.com/source-map/source-map-rfc/issues/40
In terms of code - note that the links shared by @marandaneto are packages that make use of regular source-maps without our custom extensions. I'd recommend also looking at the dart2js deobfuscator. You'll see the use of the minified data where we translate error messages, and the use of the inline data in the logic mapping stack traces.
To address the specific question about the (
containing the mapping: there is a step in the deobfuscator that looks for the enclosing function to figure out the name. Long ago, dart2js used to produce ES5 code which contained the function
keyword. We used this to identify the enclosing function and put the mapping to the original name there. Once we started emitting ES6 code, we decided to use the open parenthesis as the unique position where we located the start of the function. Our deobfuscator is tailored to find this position as well (see sourcemap_helper#L38).
At Sentry we try to resolve the scope a token is in and use that as the function name because the name is often something like apply
with no further context. It appears in this situation that is exactly the wrong thing to do :/
It appears that produced source map mappings are generated in a quite odd name. The produced function token doesn't have a valid reference to its original name, however, brackets that are part of that scope do, eg:
Or a more concrete example:
The
A.Tt.prototype.$0
scope can’t be resolved, but columns 3 (open paren), 6 (throw), 16 (the second A), and 39 (closing brace) in the second line refer to the correct name.We worked around this in our processing pipeline here https://github.com/getsentry/symbolic/pull/786 but would be great to understand how is this exactly produced, how should we interpret this, and potentially fix (if one applies) this in future releases.
I was asked to do so, thus cc: @sigmundch