This allows using the Gecko Profiler without pulling in half of Gecko (nsTArray,
nsString, etc.). This is for use in third party code, that we lightly patch to
register the threads.
Differential Revision: https://phabricator.services.mozilla.com/D116839
Crashes reported in bug 1713971 all happen after `main()` has ended, during the destruction of static objects. On Windows, `NS_IsMainThread()` returns `false` in this case.
It is suspected that this situation happens when `KillClearOnShutdown` has not been invoked, probably because XPCOM didn't even start, so the `ProfilerParentTracker` singleton has not been reset as expected before the end of XPCOM. Bug 1710620 will be looking into this scenario.
In the meantime:
At this point in time after `main()`, there should be no `ProfilerParent`s still active, so the tracking list should be empty, and the destructor would not do anything anyway. This patch allows that.
If crashes still happen then (i.e., there are still `ProfilerParent`s registered after `main()` ends), their frequency should not be worse than before, but they could give a further clue in what may be happening. And if crashes do get worse, it would be easy to revert this patch.
Differential Revision: https://phabricator.services.mozilla.com/D117125
When mozglue's MozStackWalkThread ends, the last found SP can be checked to see if it was called by JIT code, in which case we can restart the native stack walk from the known caller of the JIT code.
Differential Revision: https://phabricator.services.mozilla.com/D116379
This structure manages a list of known "ResumePoint", which contains the registers needed to restart stack walks from JIT C++ entry points.
Differential Revision: https://phabricator.services.mozilla.com/D116378
This is almost code-free: A StackWalkControl (skeleton for now) is constructed when the platform supports it, and then passed to ExtractJsFrames and the stack walker; but is not actively used yet.
Differential Revision: https://phabricator.services.mozilla.com/D113272
When mozglue's MozStackWalkThread ends, the last found SP can be checked to see if it was called by JIT code, in which case we can restart the native stack walk from the known caller of the JIT code.
Differential Revision: https://phabricator.services.mozilla.com/D116379
This structure manages a list of known "ResumePoint", which contains the registers needed to restart stack walks from JIT C++ entry points.
Differential Revision: https://phabricator.services.mozilla.com/D116378
This is almost code-free: A StackWalkControl (skeleton for now) is constructed when the platform supports it, and then passed to ExtractJsFrames and the stack walker; but is not actively used yet.
Differential Revision: https://phabricator.services.mozilla.com/D113272
Note that we can still use an existing ProfilerParentTracker instance after XPCOMShutdownThreads started (it's necessary, so that e.g., its list can be properly updated when ProfilerParents get destroyed), we just refuse to create a new one past that point.
Differential Revision: https://phabricator.services.mozilla.com/D114709
In particular, this is useful to show CPU usage graphs in no-periodic-sampling mode.
The GeckoProfiler::CPUUsage gtest was expanded to make sure that we have the same stack in this mode, and different stacks in normal sampling mode.
Differential Revision: https://phabricator.services.mozilla.com/D115892
When `respondWith` isn't called, then we run the "reset interception"
steps, which sets up a new channel and does an internal redirect. We
need a profiler network marker with the "REDIRECT" status to properly
track this.
Differential Revision: https://phabricator.services.mozilla.com/D112216
In cases where a thread is not doing anything, but hasn't been marked as asleep with `AUTO_PROFILER_THREAD_SLEEP`, we can still duplicate the previous sample if we know that zero CPU activity happened.
Differential Revision: https://phabricator.services.mozilla.com/D115454
On Windows, the profiler changes the timer resolution when the sampling interval is less than 10ms.
However this change affects all of Firefox, which can change other behaviors, sometimes causing confusion when refresh-rate issues magically disappear when the profiler is running.
So now by default the profiler will not change the timer resolution. This should rarely affect the profiler's effective sampling rate, unless all threads in a process are in a waiting state, in which case there is nothing new to sample anyway! The front-end is investigating ways to make sampling gaps more obvious, see https://github.com/firefox-devtools/profiler/issues/2962
If some power users really need the added sampling precision in some profiling sessions, the timer resolution change may be requested before running Firefox, by setting the environment variable "PROFILER_ADJUST_TIMER_RESOLUTION" to any value.
Differential Revision: https://phabricator.services.mozilla.com/D115451
`SharedLibraryInfo::GetInfoForSelf()` can use `PEHeaders::GetBounds` instead of
`GetModuleInformation` to get the start/end address of a module's mapped region
in the local process. It's roughly 100x faster because `GetModuleInformation`
invokes two system calls `NtQueryInformationProcess` and `NtReadVirtualMemory`
while `nt::PEHeaders` does not.
Depends on D115254
Differential Revision: https://phabricator.services.mozilla.com/D115255
This patch replaces two versions of `GetVersion` in Gecko profiler and
baseprofiler with `PEHeaders::GetVersionInfo`.
Depends on D115253
Differential Revision: https://phabricator.services.mozilla.com/D115254
This patch is the actual fix for Bug 1702086. The problem of Bug 1702086 is that
`LoadLibraryExW` loaded the module onto an address different from the original
mapped addresss because it was unloaded after we started enumeration. Calling
`GetPdbInfo` with the original address `module.lpBaseOfDll` caused a crash.
The proposed fix consists of three parts.
The first part is to get PDB information from `handleLock`, which is always valid
even if the original address was unloaded. With this, we don't need a check
of `VirtualQuery`.
The second part is to add `LOAD_LIBRARY_AS_IMAGE_RESOURCE` along with
`LOAD_LIBRARY_AS_DATAFILE` to the call to `LoadLibraryEx`. This is needed
to read information from the sections outside the PE headers because
RVA (= relative virtual address) is an address after relocation.
Without `LOAD_LIBRARY_AS_IMAGE_RESOURCE`, a module is mapped without relocation,
so `GetPdbInfo()` accesses wrong memory resulting in a crash.
The third part is to introduce `PEHeaders::GetPdbInfo`, replacing two versions
of `GetPdbInfo` in Gecko profiler and baseprofiler.
Depends on D115252
Differential Revision: https://phabricator.services.mozilla.com/D115253
This patch introduces `EnumerateProcessModules` to enumerate all loaded modules
in the local process so that Gecko profiler and baseprofiler can use it.
Differential Revision: https://phabricator.services.mozilla.com/D115252
When not profiling, ShutdownProfilerChild should be quick, so it's safe to run synchronously.
In this case, we don't need to manually shutdown the thread (to wait for the previously-async task).
This removes the risky thread-shutdown with its inner event-handling loop, where all crashes in bug 1613798 happen.
Differential Revision: https://phabricator.services.mozilla.com/D114845
Bug 1613798 (shutdown crashes during ChildProfilerController::ShutdownAndMaybeGrabShutdownProfileFirst's nsThread::Shutdown) could be explained by another nested shutdown destroying the same thread first, so when coming back to the first inner loop, there's a UAF on the already-destroyed thread!
Now we first reset the `mThread` pointer so it cannot be used by later/nested function calls, but keep a local reference (which should be the last one) to dispatch the shutdown operations and then shutdown the thread itself.
Also the thread pointer is now encapsulated in a DataMutex, in case it is accessed from different threads (e.g., the main thread and the IPC reception thread.)
Differential Revision: https://phabricator.services.mozilla.com/D113304