Bug 1103094 - Start profiling subprocesses if the parent process is already profiling
This is blocking bug 1182595 , which is preventing us from getting profiles for various talos tests on our talos machines (and locally).

So time to solve this.

My idea is to send down a struct with profiler data when the ContentChild sends SendGetXPCOMProcessAttributes.

That's assuming I can determine what the profile settings are in the parent at the time of creation of a content process while the profiler is already running.

Ooooohhh - it looks like I added an XPCOM interface that exposes the things I want. I suppose I can maybe get an nsIProfilerStartParams from nsIProfiler if I add a getter?

Yes! I think I can do that.

Ok, game plan:

Expose a way of getting start params from nsIProfiler
Add a reference to the features string to GeckoSampler, I guess

Huh - it looks like GeckoSampler doesn't hold on to the features string, but flips a bunch of internal settings. I should modify it to hold on to the starting string as well.

Same for things like the entry size, the feature count, the thread name filters, and the filter count.

Ah, the good news is that the Sampler class, which GeckoSampler extends, exposes the entry size, interval, etc. I just need to expose the thread names and features.

Grawr - I thought mozilla_sampler_get_features would be useful, but it's not - it returns a static list of _supported_ features, not the current active features.

So I guess I need to expose something better. Actually, what might be useful is to have a Gecko-only (so ifdef'd out for SPS_STANDALONE) method that returns an nsIProfilerStartParams from platform.cpp...

So here's a problem - the GeckoSampler converts a const char** into a mozilla::Vector<std::string> (which, according to http://www.cplusplus.com/reference/string/string/ , is char).

Then we need extract the vectors again and turn them back into an nsTArray<nsCString>, which seems rather silly.

Why can't nsIProfilerStartParams use mozilla::Vector<std::string>?

Ohhhh… one thing I just learned is that you get at the char* of a std::string via .c_str(). That's handy.

Create a new struct that can be passed through IPC that both PContent.ipdl and PPluginModule.ipdl can use
Update the start profiler messages to use that new struct
Update SendGetXPCOMProcessAttributes and the parent receiver to pass the struct down

AHHHHHH  SHIT, there's more to this.

It looks like the tps profiles aren't being gathered because the content process exits before we send a message down to gather the profiles.

So we have to solve that problem now too. I'm now less confident that the patch I wrote here is necessary to fix this problem (though it's still useful to fix).

General idea:

  • Tie lifetime of ProfileGatherer in the parent to the window of time in which we're profiling.
  • If a ContentParent starts up while we're already profiling, grab a reference to the ProfileGatherer
  • If a ContentParent notices that we've stopped profiling, have it drop the reference to ProfileGatherer.
  • If a ContentParent notices that we've started profiling, have it grab a reference to the ProfileGatherer.
  • If a ContentChild is shutting down and we're profiling, blast up a profile to the parent, and have ContentParent notify the ProfileGatherer.
  • Extend ProfileGatherer so that it can accept an array of ended-process profiles. Have a 5 profile cap on this.
  • When the actual gathering starts, have ProfileGatherer dump out the ended-process profiles as well as the ones for already-existing profiles, and then drop the ended-process profiles.
    • Alternatively, smartly drop any profiles that are outside of our sampling window.


Expose ProfileGatherer as an nsISupports on nsIProfiler
Make ProfileGatherer be alive during the profiling window
Make new ContentParents and PluginModuleParents

Actually, I've opened a new bug to do this work. This is bug 1193838 .

Got review!

Try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=36ac5b643861
And another using DebugOnly: https://treeherder.mozilla.org/#/jobs?repo=try&revision=ff5986f8f93b

Lessons: DebugOnly<nsresult> rv for MOZ_ASSERTs.