Closed Bug 1776694 Opened 2 years ago Closed 2 years ago

For local builds on desktop, we don't get symbols for libraries which are only loaded in child processes (plugin-container, libmozavcodec.so)

Categories

(Core :: Gecko Profiler, defect, P2)

defect

Tracking

()

RESOLVED FIXED
113 Branch
Tracking Status
firefox113 --- fixed

People

(Reporter: mstange, Assigned: canova)

References

(Blocks 1 open bug)

Details

(Whiteboard: [fxp])

Attachments

(10 files, 1 obsolete file)

(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details

Example profiles: https://share.firefox.dev/3HYUtnV , https://share.firefox.dev/3ynoWc5

Steps to reproduce:

  1. Build Firefox locally.
  2. Run the build and capture a profile.
  3. Check the content process and the RDD process.

Expected results:
Every library that was compiled as part of the local build should have symbols.

Actual results:
On macOS, in the child process, there's an unsymbolicated frame near the root of the call tree in plugin-container.
On Linux, in the RDD process, the frames for libmozavcodec.so are unsymbolicated.

More generally, any library which is not loaded in the parent process doesn't have symbols.

This is because we use Services.profiler.sharedLibraries to determine which absolute paths symbolication is allowed to access. It only returns libraries that are loaded in the parent process.

https://searchfox.org/mozilla-central/rev/bf6f194694c9d1ae92847f3d4e4c15c2486f3200/devtools/client/performance-new/popup/background.jsm.js#318-336

const profileCaptureResult = await Services.profiler
  .getProfileDataAsGzippedArrayBuffer()
  .then(
    profile => ({ type: "SUCCESS", profile }),
    error => {
      console.error(error);
      return { type: "ERROR", error };
    }
  );

const profilerViewMode = getProfilerViewModeForCurrentPreset(pageContext);
const sharedLibraries = Services.profiler.sharedLibraries;
const objdirs = getObjdirPrefValue();

const { createLocalSymbolicationService } = lazy.PerfSymbolication();
const symbolicationService = createLocalSymbolicationService(
  sharedLibraries,
  objdirs
);

We should call createLocalSymbolicationService with a list of libraries which contains libraries loaded in all processes.

We could get such a list by traversing the subprofiles in profileCaptureResult. But this would mean that we would have to parse the array buffer as JSON, which would materialize the full parsed profile in the memory of the parent process, which is slow and takes up memory.

We should investigate whether we can instead get an integrated list of all shared libraries from nsIProfiler.
In other conversations we've had recently (JS source code, source maps, JIT symbols) we've tossed around the idea to return some "supplemental" information along with the profile array buffer; we could put the integrated list in that supplemental information object.

Summary: For local desktop builds, we don't get symbols for libraries which are only loaded in child processes (plugin-container, libmozavcodec.so) → For local builds on desktop, we don't get symbols for libraries which are only loaded in child processes (plugin-container, libmozavcodec.so)
Severity: -- → S3
Priority: -- → P2

Julien, I think this bug would be a good place to start building out the ProfileWithInfo infrastructure: We need an nsIProfiler API which returns the profile itself as an array buffer (gzipped or not, I don't know), and along with it some JS-consumable extra info which the privileged profiler JS can look at without having to JSON-parse the entire profile. In this bug, the extra info would just be the list of shared libraries. And this extra info should be accumulated from all processes. The other processes would send it up to the parent process in the same IPC call as they send the profile JSON itself, so this IPC call will need to get a new argument with an IPC-serializable type (e.g. ProfileExtraInfo).

Would you like to take a stab at this?

Once we have this infrastructure, it'll also be used for the implementation of the JS source view, source maps, and JIT profiling.

Flags: needinfo?(felash)

We can leave the Android case out of the initial implementation. When profiling Android, we currently parse the entire profile into a JS object anyway, which is covered by bug 1581963.

Yeah, I can try looking at this soon!

Flags: needinfo?(felash)
Assignee: nobody → felash
Whiteboard: fxp
Whiteboard: fxp → [fxp]
Status: NEW → ASSIGNED
Attachment #9319016 - Attachment description: WIP: Bug 1776694 - Extract the location where the library info is retrieved to outside of the writer → WIP: Bug 1776694 - Return the library info from the JSON generation functions
Attachment #9319510 - Attachment is obsolete: true
Assignee: felash → canaltinova
Attachment #9319014 - Attachment description: WIP: Bug 1776694 - Implement move operator for SharedLibraryInfo → Bug 1776694 - Implement move operator for SharedLibraryInfo r?mstange!
Attachment #9319015 - Attachment description: WIP: Bug 1776694 - Return a Result object from profiler_stream_json_for_this_process → Bug 1776694 - Return a Result object from profiler_stream_json_for_this_process r?mstange!
Attachment #9319016 - Attachment description: WIP: Bug 1776694 - Return the library info from the JSON generation functions → Bug 1776694 - Return the library info from the JSON generation functions r?mstange!
Attachment #9319511 - Attachment description: WIP: Bug 1776694 - Make GrabShutdownProfile return the additional information as well → Bug 1776694 - Make GrabShutdownProfile return the additional information as well r?mstange!
Attachment #9319722 - Attachment description: WIP: Bug 1776694 - Add a method to SharedLibraryInfo that would add all the entries from another SharedLibraryInfo instance → Bug 1776694 - Add a method to SharedLibraryInfo that would add all the entries from another SharedLibraryInfo instance r?mstange!
Pushed by canaltinova@gmail.com: https://hg.mozilla.org/integration/autoland/rev/0ce9f03d3142 Implement move operator for SharedLibraryInfo r=mstange https://hg.mozilla.org/integration/autoland/rev/1d4524a65bbf Return a Result object from profiler_stream_json_for_this_process r=mstange https://hg.mozilla.org/integration/autoland/rev/61a720cb90f1 Return the library info from the JSON generation functions r=mstange https://hg.mozilla.org/integration/autoland/rev/4fe9056b071b Make GrabShutdownProfile return the additional information as well r=mstange https://hg.mozilla.org/integration/autoland/rev/4791ee289eb6 Add a method to SharedLibraryInfo that would add all the entries from another SharedLibraryInfo instance r=mstange https://hg.mozilla.org/integration/autoland/rev/0527899014b2 Implement ParamTraits for shared library and additional information structs r=mstange https://hg.mozilla.org/integration/autoland/rev/c80a01cb9bc5 Transfer the profile additional information from children processes to parent r=mstange https://hg.mozilla.org/integration/autoland/rev/700a30a5a8de Gather all the additional information from children and return it from StartGathering r=mstange https://hg.mozilla.org/integration/autoland/rev/479ecea2cb14 Return profile with additional info from GetProfileDataAsGzippedArrayBuffer r=mstange https://hg.mozilla.org/integration/autoland/rev/3323b6f7c34f Use the shared libraries that's provided by getProfileDataAsGzippedArrayBuffer r=mstange
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: