Self Identifying JavaScript/Hermes Source Maps (Debug IDs) #1122
Replies: 3 comments
-
Thank you for the detailed write up! After giving it some thought, I see two significant complications for a potential JS API exported in HermesInternal:
This is just the opening of the discussion, I don't have any final opinions yet. |
Beta Was this translation helpful? Give feedback.
-
Hi, thank you for the answer, I've been thinking about the most common RN use case too much, thus focusing only on one bundle. I've been exploring the Hermes source code a bit more and I've found hermes/include/hermes/BCGen/HBC/BytecodeFileFormat.h Lines 151 to 164 in 6d04fa1 I suppose, there is the same issue as with the Epilog, the footer is not read by the Hermes VM. And to read it someone with knowledge of the bundle file is needed. Considering this it seems to me like a function that could live in Based on your second point, does Hermes VM keep any information about the loaded bundles? Something from their header? |
Beta Was this translation helpful? Give feedback.
-
@krystofwoldrich So, the main problem that remains to be solved is identifying the bundle. We do keep track of the loaded "bundles" - instances of
These do get garbage collected when they are not used, but ordinarily there are at least two. I wonder whether it makes sense to expose an API that simply returns a list of the hashes of all loaded bundles where that hash is non-zero. We can ensure that |
Beta Was this translation helpful? Give feedback.
-
At Sentry, we handle a significant number of React Native stack traces, which require access to source maps. Therefore our users need to upload their source map to our server, so we can provide them with a symbolicated stack trace. But how do we know which source map is the correct one? How does the user know?
Current state
Currently, there is no way of identifying a source map and linking it to a generated bundle. This is an issue also on the web, if interested you can read https://sentry.engineering/blog/the-case-for-debug-ids with more details on the proposed
Debug IDs
.The only way of knowing a generated bundle and source maps belong together is to pack them together when a release of an app is created. This doesn't always work as a developer might have source maps disabled or lose the source map file of the released app.
Before writing this post we briefly discussed this with @tmikov who suggested
Hermes Epilog
as a possible carrier of thedebugId
identifying the bundle and its source map.For me and anyone else not familiar with it,
Hermes Epilog
is content appended to the Hermes Bundle after the Hermes Bytecode. I believe the preferred variant is a plain text JSON object.Future
Although we are in the Hermes repository, this definitely involves React Native, to my knowledge
hermesc
doesn't createHermes Epilog
thus it must be appended to the bundle file afterward in the process of creating React Native app.The next steps describe the whole process of creating the final Hermes bundle including Metro to paint a complete picture of the possible use of Debug IDs in React Native.
Example
The Bundle has
//# debugId=DEBUG_ID
at the end of the file.The Source map has a new debugId attribute that holds the Debug ID.
RN provides API to retrieve the Debug ID in runtime. Can be filled at the beginning of the bundle into a global variable by Metro. For multiple bundles map (stack trace to debug id) should be injected. Example Metro Serializer Virtual Debug ID module https://github.com/getsentry/sentry-react-native/pull/3164/files#diff-440358ee49d94fb2d6ea2ce7df3c96f0e10de487e8ed35e15ad937af85061fddR19-R34
hermesc
generates a Hermes bytecode bundle and source map.combine-source-map.js
combines Metro and Hermes source maps.{ "debugId": "HERMES_BUNDLE_FILE_HASH" }
and remove plain js debug id from the combined source map if present and add"debugId": "HERMES_BUNDLE_FILE_HASH"
.Use in runtime
Currently, Hermes offers API to read the Epilog in runtime in Java and C++. Ideally, the Debug ID can be read directly in JS right at the start before any polyfills and RN are loaded. This is important as the Debug ID will be reported with a captured error therefore must be available when the error happens.
Current API
Requires to load Hermes Bytecode bundle manually then it extracts the epilog.
hermes/API/hermes/hermes.h
Lines 66 to 71 in 7af9729
Discussion
We are happy to hear if this solves issues for you too.
HermesInternal.getEpilog();
be added to Hermes?Do you have any other comments? Please, share them under this post.
Beta Was this translation helpful? Give feedback.
All reactions