The shutdown code of BackgroundReadFiles races with BeginBackgroundRead.
This is paritally obfuscated by the usage of the initialEvent convenience
of NS_NewNamedThread, so this change also removes that in favour of explicit
dispatch. (xpcom devs want to remove the convenience anyway)
Differential Revision: https://phabricator.services.mozilla.com/D94877
The previous patch removed the only two uses of ProfilerStringView::String().
Since it can be potentially expensive (creating a `std::string` object, sometimes allocating a buffer, and copying the string contents), it's best to remove it completely.
Differential Revision: https://phabricator.services.mozilla.com/D95116
For consistency with `JSONWriter` (which UniqueJSONStrings' functions use), and for added safety and some efficiency, UniqueJSONStrings now takes `Span<const char`> arguments instead of raw pointers to null-terminated strings.
Differential Revision: https://phabricator.services.mozilla.com/D95114
Document the class and methods.
`GetOrAddIndex` is only used internally, so it can be private.
`SpliceStringTableElements` can now only work on rvalue UniqueJSONStrings, this emphasizes that it shouldn't be used anymore after this call.
Differential Revision: https://phabricator.services.mozilla.com/D95113
Most of this patch is a dance to avoid size flickering of the skeleton UI
window. We change all Resize/Move/SetSizeMode calls from before the first
nsWindow::Show call. Normally those have no effect, since the window isn't
shown yet, and if the window is not maximized, they typically match the
sizes we've gotten out of the registry anyway. However, if we are maximized,
then they produce a lot of visual noise. We can however achieve the desired
effect by just calling SetWindowPlacement.
Similarly, we switch the window styles of the skeleton UI window to match those
of the toplevel Windows window, and adjust the client rect from our window proc
in a way that matches the adjustments in nsWindow in the WM_NCCALCSIZE handler.
We do this because otherwise we get a flicker as soon as we change the styles
and nonclient margins as the fake chrome pops up and then back down.
Lastly we also change the extended window styles so that they match. We
historically added WS_EX_TOOLWINDOW here to hide the toolbar entry, because it
would otherwise switch out to a new toolbar entry when we changed the window
styles. However since our new styles match, we no longer need to do this. It
was also causing the maximized window to paint over the Windows taskbar.
Differential Revision: https://phabricator.services.mozilla.com/D93534
For a better user experience during slow startups (and to match the design
by Markus Jaritz), we want to animate the placeholder elements (the grey
rectangles which hold the place of text and icons) with a light moving
gradient.
A question may arise regarding whether the performance cost of running this
animation is worth the improved user experience. My claim is yes, hinging
mostly on the observation that the performance cost is small.
On my machine, one frame of the animation takes at most 0.15ms, and runs
every 16.15ms. This means we eat less than 1% CPU time on one core of the
system. It should also be noted that this animation runs primarily during
the window wherein we are prefetching dlls, AKA while we are blocked on IO
and the CPU is more likely to be idle.
On slower systems, one frame may take longer - however, on slower systems
we should also be blocked *more* by IO, making the trade favorable.
For further anecdotal evidence of this being okay, when I run this on slow
reference hardware shortly after OS startup, I do not see any dropped frames,
indicating that this has very little trouble completing, and is thus quite
cheap.
Regarding testing, I will invoke the same logic as for the rest of the
skeleton UI patches - it would involve quite a bit of work to test this in
automation given our existing frameworks. It may be worth it at some point,
but certainly not while this is a feature that we are just experimenting
with and which is not enabled by default.
Differential Revision: https://phabricator.services.mozilla.com/D91453
One of the scenarios in TestMMPolicy.exe is to reserve all regions but one free
region, and then FindRegion can find that free region. However, it intermittently
failed to find a free region on 32bit. Probably a different thread invoked by
the system reserved it before the main thread does. A proposed fix is to limit
the address range to reserve.
Differential Revision: https://phabricator.services.mozilla.com/D95188
Most of this patch is a dance to avoid size flickering of the skeleton UI
window. We change all Resize/Move/SetSizeMode calls from before the first
nsWindow::Show call. Normally those have no effect, since the window isn't
shown yet, and if the window is not maximized, they typically match the
sizes we've gotten out of the registry anyway. However, if we are maximized,
then they produce a lot of visual noise. We can however achieve the desired
effect by just calling SetWindowPlacement.
Similarly, we switch the window styles of the skeleton UI window to match those
of the toplevel Windows window, and adjust the client rect from our window proc
in a way that matches the adjustments in nsWindow in the WM_NCCALCSIZE handler.
We do this because otherwise we get a flicker as soon as we change the styles
and nonclient margins as the fake chrome pops up and then back down.
Lastly we also change the extended window styles so that they match. We
historically added WS_EX_TOOLWINDOW here to hide the toolbar entry, because it
would otherwise switch out to a new toolbar entry when we changed the window
styles. However since our new styles match, we no longer need to do this. It
was also causing the maximized window to paint over the Windows taskbar.
Differential Revision: https://phabricator.services.mozilla.com/D93534
For a better user experience during slow startups (and to match the design
by Markus Jaritz), we want to animate the placeholder elements (the grey
rectangles which hold the place of text and icons) with a light moving
gradient.
A question may arise regarding whether the performance cost of running this
animation is worth the improved user experience. My claim is yes, hinging
mostly on the observation that the performance cost is small.
On my machine, one frame of the animation takes at most 0.15ms, and runs
every 16.15ms. This means we eat less than 1% CPU time on one core of the
system. It should also be noted that this animation runs primarily during
the window wherein we are prefetching dlls, AKA while we are blocked on IO
and the CPU is more likely to be idle.
On slower systems, one frame may take longer - however, on slower systems
we should also be blocked *more* by IO, making the trade favorable.
For further anecdotal evidence of this being okay, when I run this on slow
reference hardware shortly after OS startup, I do not see any dropped frames,
indicating that this has very little trouble completing, and is thus quite
cheap.
Regarding testing, I will invoke the same logic as for the rest of the
skeleton UI patches - it would involve quite a bit of work to test this in
automation given our existing frameworks. It may be worth it at some point,
but certainly not while this is a feature that we are just experimenting
with and which is not enabled by default.
Differential Revision: https://phabricator.services.mozilla.com/D91453
Poison was setup at the start of xpcom init when that was assumed to be early enough.
Since then, Poison was added to Maybe, and Maybe has been used everywhere, including in
our channel implementation. As a result, poison was being used before it was initialized.
This basically meant our poison pointers were being replaced with null instead, which
dances into some more UB than accessing a page we have actually allocated. Also, tsan
noticed that accesses to the value were racing with the initializer actually being
called!
A (dynamic) static initializer forces the poison initialization as we can reasonably
hope without getting CallOnce or singleton patterns involved.
Other changes:
* Cleaned up the outdated documentation for mozWritePoison (the alignment
restriction was removed in Bug 1414901)
* Removed the poison supression from TSan
Differential Revision: https://phabricator.services.mozilla.com/D94251
If the urlbar is zoomed (defined by attribute breakout-extend), then we
scale it down to the unfocused coordinate values.
Differential Revision: https://phabricator.services.mozilla.com/D92303
The latest launcher process showed one of the top failures was `WriteProcessMemory` in
`CopyStubToChildProcess` failed with `ERROR_INVALID_ADDRESS` or `ERROR_NOACCESS`, that
is to store a trampoline address to the global variable of firefox.exe failed. Its root
cause should be the same as bug 1662560, the executable was loaded onto a different
address from the browser process.
The fix is to to expand the usage of `CrossExecTransferManager` to `FuncHookCrossProcess`
and `Kernel32ExportsSolver`.
Depends on D94652
Differential Revision: https://phabricator.services.mozilla.com/D94653
This patch introduces a class `CrossExecTransferManager` to manage the data
transfer from the current process to a remote process via `WriteProcessMemory`.
The class also encapsulates a logic to bridge the gap between two executable's
imagebase.
Differential Revision: https://phabricator.services.mozilla.com/D94652
This commit uses the new Markers 2.0 API for FileIO Markers. I had to
create another option for the MarkerStack class in order to conditionally
capture a backtrace inside of the Macro. Otherwise the macro invocation
failed.
Differential Revision: https://phabricator.services.mozilla.com/D93848
The new Markers 2.0 code had missed one detail:
Backtraces in markers were serialized as just the `ProfileChunkedBuffer`, which doesn't expose the original thread id like `ProfilerBacktrace` did.
Then when outputting the profile, the marker code would use the marker's thread id (where the marker should be displayed in the frontend, which *could* be different from where the backtrace came) to deserialize and stream the attached marker, and a special check in the streaming code meant that the mismatched id would ignore the stored sample, and the displayed marker would show no stack.
With this patch, when streaming stacks from markers, the given thread id is 0 (an impossible thread id), which indicates that whatever sample is present should be streamed.
`ProfilerBacktrace` doesn't need to store the thread id anymore.
This solves the above problem.
As a bonus, the streaming code now reports the original thread of the sample(s) it found. This could be used in the future, to better show in the frontend that some stacks may come from other threads.
Differential Revision: https://phabricator.services.mozilla.com/D94264
This commit uses the new Markers 2.0 API for FileIO Markers. I had to
create another option for the MarkerStack class in order to conditionally
capture a backtrace inside of the Macro. Otherwise the macro invocation
failed.
Differential Revision: https://phabricator.services.mozilla.com/D93848
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.
5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.
5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
To produce this patch I did all of the following:
1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
2. Run ./mach lint --linter black --fix
3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
4. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
# ignore-this-changeset
Differential Revision: https://phabricator.services.mozilla.com/D94045
The latest launcher process ping showed one of the reasons why we failed to
detour `NtMapViewOfSection` is that `MMPolicyBase::FindRegion` failed to find
a free region. Inspecting the function carefully, there were three problems.
Firstly, `FindRegion` did not fully scan the given range. To randomize
the address of a free region we use, we start scanning from a random address
within the given range. The problem is we scan only addresses bigger than
that random address, without scanning smaller addresses. Probably this is
the reason why `FindRegion` fails.
Secondly, `FindRegion` may return an address not aligned with the allocation
granularity because `VirtualQueryEx` returns such an address. If that happens,
the subsequent mapping API fails with the alignment error.
Lastly, when we randomize an address to start scanning from, we divide a random
number by `maxOffset`, but with that, we never start scanning from the last
region. It does not affect the product's behavior, but to have fair randomization,
a divisor should be `maxOffset + 1`.
This patch fixes all of these three problems along with a new test program.
Differential Revision: https://phabricator.services.mozilla.com/D94110
Everything related to Base Profiler legacy markers can now be removed, only the new API from BaseProfilerMarkers.h should now be used.
Depends on D93737
Differential Revision: https://phabricator.services.mozilla.com/D93738
TextMarkerPayload is the only legacy marker type that is still used in the Base Profiler. We're converting it to the new BASE_PROFILER_MARKER_TEXT.
Depends on D93736
Differential Revision: https://phabricator.services.mozilla.com/D93737
Since the main thread is almost always being profiled, this makes it easy to direct important markers there (e.g., FileIO markers from unregistered threads).
Tech note: The `#include "BaseProfiler.h"` line was moved to BaseProfilerMarkersPrerequesites.h so that `MarkerThreadId::MainThread()` there can access `profiler_main_thread_id()`.
Depends on D93735
Differential Revision: https://phabricator.services.mozilla.com/D93736
These functions will be useful to get the main thread id, or check if we're in it, in some public code (e.g., markers).
Differential Revision: https://phabricator.services.mozilla.com/D93735
These unit tests were going through chunks very quickly in tight loops, which on some platforms could cause successive chunks to be marked "done" with the same timestamps.
Distinct timestamps are needed to uniquely identify chunks (in each process), and related assertions caught that. In real Firefox code, chunks are much bigger (around 1MB), and fill at a slower rate, so timestamps are always different as expected there.
To fix this artificial issue in our unit tests, delays are introduced before each `MarkDone()`, to ensure that they'll get a different timestamp every time.
Differential Revision: https://phabricator.services.mozilla.com/D93479
Along with the deserializer, we now also store other marker functions (that output the marker type name and schema).
These will be used in the following patch to output the combined schema list for all used marker types.
Differential Revision: https://phabricator.services.mozilla.com/D90659
Add `static mozilla::MarkerSchemaWriter MarkerTypeDisplay()` for each existing marker type.
Because all markers of a given type now must have the same payload and display schema, the DOM event marker has changed from type=tracing with category=DOMEvent, to its own type=DOMEvent, which is now accepted on the front-end.
Based on c9692715f2/src/profile-logic/marker-schema.js
Differential Revision: https://phabricator.services.mozilla.com/D90658
This class collects all the information necessary to stream the JSON schema that informs the front-end how to display a type of markers.
It will be created and populated in `MarkerTypeDisplay()`, functions in each marker type definition, with Add/Set functions (see following patch).
Based on c9692715f2/src/profile-logic/marker-schema.js
Differential Revision: https://phabricator.services.mozilla.com/D90657
`AutoArraySchemaWriter::FreeFormElement()` is never used, we can remove it.
When constructed, `AutoArraySchemaWriter` was optionally taking a `UniqueStrings` reference, which was stored as a pointer.
Then `AutoArraySchemaWriter::StringElement()` would do a dangerous `MOZ_RELEASE_ASSERT(mStrings);`.
The class is now split in two:
- `AutoArraySchemaWriter`, which does not deal with strings at all, so we don't need a pointer to `UniqueStrings`.
- `AutoArraySchemaWithStringsWriter` that can also deal with strings, in which we store a (non-null) `UniqueStrings` reference.
This is both:
- Safer, because it's not possible to instantiate the non-string writer and try to write a string.
- More efficient, because we don't need to pass&store a `UniqueStrings` reference/pointer when we don't deal with strings.
Differential Revision: https://phabricator.services.mozilla.com/D93191
This is the third attempt to investigate the launcher failure of our detour.
The previous commits d8315e4ed18d and 1b81ea85c43d added the assembly bytes
of a detour target and a special error code `DetourResultCode` to the launcher
failure ping.
In the latest telemetry data, however, the most common value of `hresult`
is still `ERROR_UNIDENTIFIED_ERROR`, meaning the previous commit missed to
set an error code in the common fallible codepath we wanted to know.
Besides `ERROR_UNIDENTIFIED_ERROR`, we're seeing `DETOUR_PATCHER_DO_RESERVE_ERROR`
in the telemetry, but having that code is not enough to pinpoint a falling
operation.
For further investigation, this patch adds ten more values to `DetourResultCode`.
`FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR` is the last codepath we forgot to cover
in the previous commit. The values of `MMPOLICY_RESERVE_*` are to investigate
`DETOUR_PATCHER_DO_RESERVE_ERROR` in the MMPolicy level. In both cases, we add
the last Windows error code to `DetourError::mOrigBytes`.
Differential Revision: https://phabricator.services.mozilla.com/D92974
We blocked the older versions of database.dll as Bug 1566109 in 2019,
but the same crash is still happening with the newer versions.
We decided to block all versions because crashing in the middle of printing
or file uploading is not acceptable.
Differential Revision: https://phabricator.services.mozilla.com/D92988
It is possible to add options to a NoPayload marker, but stack and inner window ids would be lost because they are normally stored in the payload 'data' JSON object, which doesn't exist for NoPayload markers.
So in this case, we automatically change the marker to a new (internal) "NoPayloadUserData" type, which has a payload in which we can store options.
This is temporary, until bug 1646714 moves these options into the top-level marker JSON object.
Differential Revision: https://phabricator.services.mozilla.com/D93059
This is the third attempt to investigate the launcher failure of our detour.
The previous commits d8315e4ed18d and 1b81ea85c43d added the assembly bytes
of a detour target and a special error code `DetourResultCode` to the launcher
failure ping.
In the latest telemetry data, however, the most common value of `hresult`
is still `ERROR_UNIDENTIFIED_ERROR`, meaning the previous commit missed to
set an error code in the common fallible codepath we wanted to know.
Besides `ERROR_UNIDENTIFIED_ERROR`, we're seeing `DETOUR_PATCHER_DO_RESERVE_ERROR`
in the telemetry, but having that code is not enough to pinpoint a falling
operation.
For further investigation, this patch adds ten more values to `DetourResultCode`.
`FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR` is the last codepath we forgot to cover
in the previous commit. The values of `MMPOLICY_RESERVE_*` are to investigate
`DETOUR_PATCHER_DO_RESERVE_ERROR` in the MMPolicy level. In both cases, we add
the last Windows error code to `DetourError::mOrigBytes`.
Differential Revision: https://phabricator.services.mozilla.com/D92974
The latest Windows Insider Preview (version 20226.1000) changes the machine code for BaseThreadInitThunk to have a preamble like the following:
00007FFDBF244C40 48 83 EC 28 sub rsp,28h
00007FFDBF244C44 85 C9 test ecx,ecx
00007FFDBF244C46 75 25 jne 00007FFDBF244C6D
00007FFDBF244C48 49 BA 70 A2 DC 12 6A 97 99 B0 mov r10,0B099976A12DCA270h
This patch adds "MOV r64, imm64" capability to the DLL interceptor so that we can hook this.
Differential Revision: https://phabricator.services.mozilla.com/D92146
This makes it clearer where marker-type-specific payload arguments start, just after the marker type object.
Also improved the main API documentation.
Differential Revision: https://phabricator.services.mozilla.com/D91681
The `category.WithOptions(...)` syntax was a bit strange and difficult to explain.
Now the category and options are separate parameters. Default options can be specified with `MarkerOptions{}` or just `{}`.
As a special case, defaulted-NoPayload functions don't need `<>`, and defaulted-NoPayload functions and macros don't even need `{}` for default options, e.g.:
`profiler_add_marker("name", OTHER); PROFILER_MARKER_UNTYPED("name", OTHER);`
Differential Revision: https://phabricator.services.mozilla.com/D91680
This makes it clearer where marker-type-specific payload arguments start, just after the marker type object.
Also improved the main API documentation.
Differential Revision: https://phabricator.services.mozilla.com/D91681
The `category.WithOptions(...)` syntax was a bit strange and difficult to explain.
Now the category and options are separate parameters. Default options can be specified with `MarkerOptions{}` or just `{}`.
As a special case, defaulted-NoPayload functions don't need `<>`, and defaulted-NoPayload functions and macros don't even need `{}` for default options, e.g.:
`profiler_add_marker("name", OTHER); PROFILER_MARKER_UNTYPED("name", OTHER);`
Differential Revision: https://phabricator.services.mozilla.com/D91680
The previous commit d8315e4ed18d introduced a new telemetry field
in the launcher process ping to collect the assembly pattern of
a target function on detour failure, but most of the crash instances
do not have a value in the field. This means the failure happens
before or after `CreateTrampoline`.
To narrow down the root cause, this patch puts a fine-grained error value
in the "hresult" field instead of the hardcoded ERROR_UNIDENTIFIED_ERROR.
This patch also adds `IsPageAccessible` check before fetching data from
a different process because fetching data from an invalid address hits
`MOZ_RELEASE_ASSERT` in `EnsureLimit`, resulting in crash without sending
the launcher process failure.
Differential Revision: https://phabricator.services.mozilla.com/D91881
The last Avast Antivirus's hook function contains `CALL [disp32]` instruction.
Our detour needs to be able to handle that pattern.
Differential Revision: https://phabricator.services.mozilla.com/D91155
This patch optimizes our detour's code handling Opcode 0xFF, expanding
its coverage to INC and DEC reg64 as well as PUSH and CALL.
Testcases for these scenarios are of course included.
Differential Revision: https://phabricator.services.mozilla.com/D91154
In the initial patches for bug 1656526, mhowell noticed that for startups which
take a very long time, if the user interacts with the skeleton UI window, the OS
will flag us as not responsive, which could be a poorer user experience than
seeing nothing. Since our UI is designed to look non-interactive anyway, we
assume that a better experience would be to simply squash the not responsive
response from the OS by trivially processing native events. It's not perfect in,
say, the event that startup is hung for some reason, but it's arguably preferable
to our old model of startup being hung, which was just nothing being displayed at
all.
Differential Revision: https://phabricator.services.mozilla.com/D91005
This saves 1 byte when serializing each marker (and removes all the code that was related to the 2nd byte).
Also it will be easier to use it in legacy code that only knows about the category pair.
Added unit tests for the whole of MarkerCategory.
Differential Revision: https://phabricator.services.mozilla.com/D91110
This patch uses the prefs relevant to the pre-xul skeleton UI to control the
registry value. There are three prefs:
- A new pref intended to be the global toggle once all themes can be handled.
- browser.startup.blankWindow - we currently depend on the code in BrowserGlue.jsm,
gated on this pref, which immediately specifies the width and height of the
window and ultimately causes XUL to consume and take ownership of our pre-xul
window. Without this, we resize to fit a small content area, and then resize
again back to the correct size.
- extensions.activeThemeID - Given that we have hardcoded layout and colors, we
need to ensure that we're only presenting the skeleton UI for the default theme.
We're hoping to not need to gate on any prefs other than the new pref that we're
adding, but this allows us to provide a simple direction for users who may want
to dogfood our changes in the mean time: use the default theme, ensure the
browser.startup.blankWindow pref is set, and turn our new pref on.
Differential Revision: https://phabricator.services.mozilla.com/D90884
This patch bypasses `-Wunused-lambda-capture` warnings by using `Unused` as
Bug 1375386 did. Having two definitions with `#ifdef` confuses clang-format.
Using `Unused` seems like the easiest approach.
Differential Revision: https://phabricator.services.mozilla.com/D90610
Many instances of the launcher failure ping indicate hooking NtMapViewOfSection
or LdrLoadDll failed. This is most likely caused by a third-party application
applying a hook onto the same target earlier than we do.
This patch is to add a new field "detour_orig_bytes" in the laucnher failure ping
to collect the first sixteen bytes of a detour target function. With this,
we can know whether those detour failures were caused by a third-party hook or not,
and if yes, what was the actual binary pattern.
Differential Revision: https://phabricator.services.mozilla.com/D89836
This is currently failing the tier 2 MinGW-Clang builds, complaining
that DPI_AWARENESS_CONTEXT is not defined. Accordingly I pulled out the
logic from WinUtils.h which ensures it is defined into a shared header.
Differential Revision: https://phabricator.services.mozilla.com/D90467
Many instances of the launcher failure ping indicate hooking NtMapViewOfSection
or LdrLoadDll failed. This is most likely caused by a third-party application
applying a hook onto the same target earlier than we do.
This patch is to add a new field "detour_orig_bytes" in the laucnher failure ping
to collect the first sixteen bytes of a detour target function. With this,
we can know whether those detour failures were caused by a third-party hook or not,
and if yes, what was the actual binary pattern.
Differential Revision: https://phabricator.services.mozilla.com/D89836
The earlier fix ea452bb92e6a proved the executable's imagebase in a child
process is not always the same as the local imagebase. This patch applies
the new approach to retieve the imagebase from a handle to all channels.
Interestingly, we observed the launcher failures at `VirtualProtectEx` only
when launching a sandboxed process, not when launching the browser process.
In the long term, we may need to take care of all `WriteProcessMemory` calls
for a child process for greater safety, but given that observation, this
patch only updates `RestoreImportDirectory` and `InitializeDllBlocklistOOP`.
Differential Revision: https://phabricator.services.mozilla.com/D90316
We need this because otherwise we load user32, which fails the check in
WindowsDllBlocklist.cpp (line 649). It sounds like this check is non-
negotiable, so this is the only solution I can come up with. Obviously
please let me know if there is some reason we cannot do this, but it
seems to function fine.
Depends on D89670
Differential Revision: https://phabricator.services.mozilla.com/D90271
Hopefully the comments in the actual code are enough to explain what is going
on here.
NOTE: this patch does not represent a finished skeleton UI. There are some
questions in comments within the code, and generally I'm seeking feedback on
whether the overall approach seems sane or not. Gijs, I'm including you for
feedback on whether you think this is maintainable by more frontend-oriented
folks, and Molly, I'm including you for feedback on whether the justification
for writing to a raw pixel buffer seems sound or not, and a general review of
the approach.
Differential Revision: https://phabricator.services.mozilla.com/D86447
See bug for justification. This patch aims to display a blank window prior to
loading/prefetching xul.dll. It also has a placeholder for drawing a
skeleton UI into that window. Note that this is disabled by default based on
a registry value, as there are still kinks to work out (for instance, what
happens if we aren't actually going to display a window, because, say, Firefox
is already running.) This just gives a basic implementation to dogfood, and
facilitates distributing work across multiple contributors.
Onto the details. The patch achieves its goal by creating a window and
assigning its handle to a static variable, which will be consumed inside
nsWindow::Create by the first toplevel window we want to make. nsWindow::Create
will take ownership of the window handle, restyle it to its own liking, and
then proceed as if everything is normal and it had created the window itself.
Differential Revision: https://phabricator.services.mozilla.com/D86263
In most situations, JSONWriter users already know string lengths (either directly, or through `nsCString` and friends), so we should keep this information through JSONWriter and not recompute it again.
This also allows using JSONWriter with sub-strings (e.g., from a bigger buffer), without having to create null-terminated strings.
Public JSONWriter functions have overloads that accept literal strings.
Differential Revision: https://phabricator.services.mozilla.com/D86192
Hopefully the comments in the actual code are enough to explain what is going
on here.
NOTE: this patch does not represent a finished skeleton UI. There are some
questions in comments within the code, and generally I'm seeking feedback on
whether the overall approach seems sane or not. Gijs, I'm including you for
feedback on whether you think this is maintainable by more frontend-oriented
folks, and Molly, I'm including you for feedback on whether the justification
for writing to a raw pixel buffer seems sound or not, and a general review of
the approach.
Differential Revision: https://phabricator.services.mozilla.com/D86447
See bug for justification. This patch aims to display a blank window prior to
loading/prefetching xul.dll. It also has a placeholder for drawing a
skeleton UI into that window. Note that this is disabled by default based on
a registry value, as there are still kinks to work out (for instance, what
happens if we aren't actually going to display a window, because, say, Firefox
is already running.) This just gives a basic implementation to dogfood, and
facilitates distributing work across multiple contributors.
Onto the details. The patch achieves its goal by creating a window and
assigning its handle to a static variable, which will be consumed inside
nsWindow::Create by the first toplevel window we want to make. nsWindow::Create
will take ownership of the window handle, restyle it to its own liking, and
then proceed as if everything is normal and it had created the window itself.
Differential Revision: https://phabricator.services.mozilla.com/D86263
`MarkerOptions::Set()` returns the same reference type as the object it's invoked on, i.e.: & -> &, and && -> &&.
`MarkerOptions::NAME()` now always returns a reference to a `const` member, so it's clear it cannot be modified (even if the object at hand is not `const`).
`MarkerOptions::NAMERef()` must be used when non-`const` access is needed.
Differential Revision: https://phabricator.services.mozilla.com/D89715
The name `AUTO_PROFILER_MARKER_TEXT` is more consistent with the equivalent non-`AUTO` macro, and similarly arguments have been re-ordered to be the same, i.e.: Name, category&options, text.
The different macros with different argument sets can now be collapsed into one macro, and the optional arguments (timing, inner window id, backtrace) can easily be added to the `MarkerOptions` where needed.
As a bonus, a specific start time can optionally be provided at construction time.
Differential Revision: https://phabricator.services.mozilla.com/D89588
Mostly mechanical changes, with some work needed to convert the different payloads (with optional timestamps, inner window id, and/or backtrace) to the equivalent MarkerOptions.
Differential Revision: https://phabricator.services.mozilla.com/D89587
Mostly mechanical change, with some extra work where non-literal names are provided.
Also, when this is the only profiler call in a file, `#include "GeckoProfiler.h"` can be changed to `#include "mozilla/ProfilerMarkers.h"`.
Differential Revision: https://phabricator.services.mozilla.com/D89415
Our data indicates when the browser process populates a newly-created child process,
`VirtualProtectEx` may fail with `ERROR_INVALID_ADDRESS` for some unknown reason.
One possible cause is the parameter `aRemoteExeImage` of `RestoreImportDirectory`
was wrong i.e. pointing to an invalid address. We simply pass the local process's
imagebase as `aRemoteExeImage` based on the assumption that the same executable is
mapped onto the same address in a different process, but it may not be guaranteed.
To deal with that potential case, we could retrieve a correct imagebase from the handle
of a remote process as we do for the plugin process. Since we're not so sure about
the root cause or the effectiveness of this fix, we run it only when the first
attempt to `VirtualProtectEx` failed in Nightly. Once it's confirmed, we promote this
to a permanent fix.
Differential Revision: https://phabricator.services.mozilla.com/D89502
`ProfileChunkedBuffer` needed to be fully defined, because its destructor is needed to define `UniquePtr<ProfileChunkedBuffer>`.
It can just be empty, because it won't actually be used anyway.
Added non-`MOZ_GECKO_PROFILER` tests around this.
Differential Revision: https://phabricator.services.mozilla.com/D89351
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
In Win7 and later, some exported functions in kernel32.dll are just a stub
jumping to a function in kernelbase.dll. After the fix for Bug 1642626,
our detour resolves such a stub in kernel32.dll and detours a corresponding function in
kernelbase.dll. This new behavior caused a problem in Win8 when we detour
`DuplicateHandle` because our detour cannot handle the assembly pattern of
`KERNELBASE!DuplicateHandle`.
Win8's `KERNELBASE!DuplicateHandle` has jump instructions whose destination is
within the region where we move instructions to a trampoline.
In the example below, the address `000007f954ad271c` is a destination of the
`JMP` instructions, but when we detour `KERNELBASE!DuplicateHandle`, we move
the original instructions to a trampoline, and that address will point to
an invalid instruction, jumping to which address causes a crash.
A proposed fix is to detour `KERNEL32!DuplicateHandle` without resolving redirection,
that is the behavior before bug 1642626.
```
KERNEL32!DuplicateHandle:
000007f9`54cd2d5c ff2556b61100 jmp qword ptr [KERNEL32!_imp_DuplicateHandle] --> KERNELBASE!DuplicateHandle
```
```
KERNELBASE!DuplicateHandle:
000007f9`54ad2710 4883ec48 sub rsp,48h
000007f9`54ad2714 4c8bd1 mov r10,rcx
000007f9`54ad2717 83faf4 cmp edx,0FFFFFFF4h
000007f9`54ad271a 733b jae KERNELBASE!DuplicateHandle+0x43 (000007f9`54ad2757)
000007f9`54ad271c 8b842480000000 mov eax,dword ptr [rsp+80h]
...
000007f9`54b8f0de 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0e7 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f0eb 488b5220 mov rdx,qword ptr [rdx+20h]
000007f9`54b8f0ef e92836f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f0f4 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0fd 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f101 488b5228 mov rdx,qword ptr [rdx+28h]
000007f9`54b8f105 e91236f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f10a 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f113 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f117 488b5230 mov rdx,qword ptr [rdx+30h]
000007f9`54b8f11b e9fc35f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
```
Differential Revision: https://phabricator.services.mozilla.com/D88136
This patch adds a new property `process_type` to the launcher process failure
ping, indicating which process type the browser process failed to initialize
as a sandboxed process.
Depends on D83639
Differential Revision: https://phabricator.services.mozilla.com/D83640
This patch adds winlauncher's HandleLauncherError to DllServices
along with InitializeDllBlocklistOOPInternal so that SandboxBroker
can call HandleLauncherError.
Differential Revision: https://phabricator.services.mozilla.com/D83639
Normally I believe it's good to keep functionally-distinct code in separate functions when appropriate.
However in this case, this `ChunkedJSONWriteFunc::GetTotalLength()` function was only used internally, so it's easy to hide it. It is not very big, so it's less important to keep it separate. And its code (going through all chunks to collect sizes) is similar to the code that follows (going through all chunks to collect their content), so it makes some sense to have these similar things in the same place; if one day this chunking change, both loops would probably have to be modified at the same time.
More importantly to justify this change: It was including the final null terminator, which was a bit inconsistent with the usual `Length()` functions in string containers.
Now that code is only used where absolutely necessary (before allocating an output buffer), so it rightly accounts for the null terminator that is added at the end of the contents.
And in upcoming bug 1612799, `ChunkedJSONWriteFunc` will have a new "retired" state (e.g., after an internal memory allocation failed) in which case a public `GetTotalLength()` function could give misleading results -- should it be 0 (nothing to output), 1 (only the null terminator), 5 ("null"), or the length of some error message? So I think it's better not to expose such an ambiguous function.
It could of course be re-introduced if new needs arise in the future.
Differential Revision: https://phabricator.services.mozilla.com/D87833
In most calls to `SpliceableJSONWriter::Splice(const char*)`:
- The data comes from a `ChunkedJSONWriteFunc` and is copied to a new buffer, which is then copied again through `Write()`. Instead we can copy the data directly from the `ChunkedJSONWriteFunc`; and this is a nice complement to `TakeAndSplice()` below.
- Or the length is already known, so we can pass it to a new `Splice(const char*, size_t)`, which forwards it to `Write(const char*, size_t)`, saving one `strlen` call.
Differential Revision: https://phabricator.services.mozilla.com/D87703
`SpliceableChunkedJSONWriter::ChunkedWriteFunc` returns a `ChunkedJSONWriteFunc*`, which is never null and is either used to:
1. Copy data.
2. Or take ownership of the chunks.
In the first case, `ChunkedWriteFunc()` now returns a `const ChunkedJSONWriteFunc&` (notice "const &"), so only const members may be used to copy the data.
In the second case, a new function `TakeChunkedWriteFunc()` returns `ChunkedJSONWriteFunc&&` (notice "&&"), so it's clear that its chunks can be taken away. Some `DEBUG` assertions help ensure that it's not used anymore after that.
`TakeAndSplice()` now takes a `ChunkedJSONWriteFunc&&`.
All callers have been updated to the more appropriate functions.
Differential Revision: https://phabricator.services.mozilla.com/D87702
This patch makes it possible to serialize and deserialize std::basic_string's of different character types, not just std::string. This will be useful when dealing with char16_t from nsString and others.
We also expose the internal read-contents functions, to allow the user to read a sequence of characters of already-known length.
Differential Revision: https://phabricator.services.mozilla.com/D87237
Hopefully the comments in the actual code are enough to explain what is going
on here.
NOTE: this patch does not represent a finished skeleton UI. There are some
questions in comments within the code, and generally I'm seeking feedback on
whether the overall approach seems sane or not. Gijs, I'm including you for
feedback on whether you think this is maintainable by more frontend-oriented
folks, and Molly, I'm including you for feedback on whether the justification
for writing to a raw pixel buffer seems sound or not, and a general review of
the approach.
Differential Revision: https://phabricator.services.mozilla.com/D86447
See bug for justification. This patch aims to display a blank window prior to
loading/prefetching xul.dll. It also has a placeholder for drawing a
skeleton UI into that window. Note that this is disabled by default based on
a registry value, as there are still kinks to work out (for instance, what
happens if we aren't actually going to display a window, because, say, Firefox
is already running.) This just gives a basic implementation to dogfood, and
facilitates distributing work across multiple contributors.
Onto the details. The patch achieves its goal by creating a window and
assigning its handle to a static variable, which will be consumed inside
nsWindow::Create by the first toplevel window we want to make. nsWindow::Create
will take ownership of the window handle, restyle it to its own liking, and
then proceed as if everything is normal and it had created the window itself.
Differential Revision: https://phabricator.services.mozilla.com/D86263
This change makes everything compile and presumably has some tiny effect on
performance. We also take the opportunity to ensure that the compiler won't
optimize out our inline asm by making the asm volatile and indicating that
it touches memory.
Differential Revision: https://phabricator.services.mozilla.com/D86594
The stack sampling can be abstracted to only use a reference to a `ProfileBuffer`, and the existing `locked_profiler_get_backtrace` can provide its stack-based `ProfileBuffer` that points at a heap-based `ProfileChunkedBuffer` (the one that will be stored in the returned `ProfilerBacktrace`).
And we can now add a public `profiler_capture_backtrace` that only takes a reference to a `ProfileChunkedBuffer`, and fills it with a backtrace.
This will be used by the new marker API, to optionally capture a backtrace in stack-based buffers at the user's request.
Differential Revision: https://phabricator.services.mozilla.com/D86514
A heap-allocate ProfileBuffer is not really needed, so it's more efficient to have one on the stack during capture, and we don't need to keep it in the `ProfilerBacktrace`.
Differential Revision: https://phabricator.services.mozilla.com/D86513
Instead of always taking ownership of both heap-allocated `ProfileBuffer` and `ProfileChunkedBuffer`, `ProfilerBacktrace` can now accept:
- Unique pointers to both or either, similar to what it was before, so a ProfilerBacktrace can be kept for later use.
- Non-owning pointers to both or either, to allow callers to use stack-based buffer(s); null pointers are allowed for totally empty backtraces.
Only the `ProfileChunkedBuffer` contains the actual data, we can create a `ProfileBuffer` on the spot if not provided.
Differential Revision: https://phabricator.services.mozilla.com/D86512
Instead of keeping a pointer to a null-terminated string, it's simpler to keep a proper `std::string`, and it helps to keep the length ready for streaming.
Differential Revision: https://phabricator.services.mozilla.com/D86511
Let `ProfilerBuffer` expose its underlying `ProfileChunkedBuffer`, this will be useful when `ProfilerBacktrace` will only be given a `ProfileBuffer`, and to perform some safety checks.
As a bonus from this change, `StoreMarker()` can be made non-generic -- It was relying on both `ProfileBuffer` and `ProfileChunkedBuffer` to have the same function `PutObjects()`. Consequently, we don't need `ProfileBuffer::PutObjects()` anymore, this removes this clunky pass-through (but useful and the best solution at the time).
Differential Revision: https://phabricator.services.mozilla.com/D86510
Until now the `ProfileBuffer` would erase its attached `ProfileChunkedBuffer` upon destruction.
However:
- The main `ProfileChunkedBuffer` is erased anyway in the `ActivePS`,
- Other `ProfileChunkedBuffer`s are short-lived and don't really need to be erased.
- The upcoming changes to `ProfilerBacktrace` and its users means that we will only keep the `ProfileChunkedBuffer` as backtrace storage, a `ProfileBuffer` will only be needed during capture and then when streaming to JSON; so we don't want the `ProfileChunkedBuffer` to be erased when detached from its capturing `ProfileBuffer`.
- Also, the erasing was done by `ResetChunkManager()` in `~ProfileBuffer()`, which was asymetric with what the constructor does (nothing!). So it's better to leave whoever did the `SetChunkManager()` to deal with the corresponding `ResetChunkManager()` (in the main case `ActivePS`, otherwise short-lived buffers being destroyed at the end of their scope).
Both `ProfileBuffer` destructors were only doing this operation, so we can just remove them completely.
Differential Revision: https://phabricator.services.mozilla.com/D86509
Backtraces and other marker data will be stored directly into a ProfileChunkedBuffer from public code in both profilers, so we will need to have the entry "kinds" available outside of the profiler directories.
This also helps with de-duplicating, since the kinds will now be in one spot and shared by both profilers.
Differential Revision: https://phabricator.services.mozilla.com/D86508
The registers referenced in this patch and the assembly have been tested to
compile; the code changes have not been tested to actually work.
Differential Revision: https://phabricator.services.mozilla.com/D86612
This change doesn't resolve some of the issues in profiler code that have
x86-64-isms in them, but this is at least a start.
Differential Revision: https://phabricator.services.mozilla.com/D86595
SpliceableChunkedJSONWriter::WriteFunc was hiding base-class non-virtual JSONWriter::WriteFunc(), which made it less than ideal (for me) to reason with.
Also made a few subclasses final, to help with possible devirtualization.
Differential Revision: https://phabricator.services.mozilla.com/D86505
The main change is removing ProfileJSONWriter.cpp, making ProfileJSONWriter.h point at BaseProfileJSONWriter.h, and exposing `mozilla::baseprofiler::` classes in the top namespace as expected by users of ProfileJSONWriter.h (to minimize changes).
These two headers are now always present in the "mozilla" include directory, independent of MOZ_GECKO_PROFILER settings.
The rest is just needed tweaks to match the above changes.
Differential Revision: https://phabricator.services.mozilla.com/D86504
Because this header will be used across libraries (mozglue and xul), it is simpler and more efficient to make it fully self-contained instead of using MFBT_API.
It may lead to slightly longer build times, but since it's only used inside the profilers, it won't impact other components.
The compiler can better optimize it in context, and decide what to inline.
Differential Revision: https://phabricator.services.mozilla.com/D86503
That was redundant with the manifest being added with MT (although useful
for mingw builds, that don't use MT), but is also now handled by the
automatic creation of rc files.
Differential Revision: https://phabricator.services.mozilla.com/D86156
The resource file is always generated so being able to configure its name
is not useful. On the other hand, the way things are currently implemented,
the lack of RESFILE also makes RCFILE ignored, which we fix at the same
time.
And remove a spurious RESFILE in widget/windows/moz.build, where no binary
is produced, which means RESFILE had no meaning.
Differential Revision: https://phabricator.services.mozilla.com/D86154
That was redundant with the manifest being added with MT (although useful
for mingw builds, that don't use MT), but is also now handled by the
automatic creation of rc files.
Differential Revision: https://phabricator.services.mozilla.com/D86156
The resource file is always generated so being able to configure its name
is not useful. On the other hand, the way things are currently implemented,
the lack of RESFILE also makes RCFILE ignored, which we fix at the same
time.
And remove a spurious RESFILE in widget/windows/moz.build, where no binary
is produced, which means RESFILE had no meaning.
Differential Revision: https://phabricator.services.mozilla.com/D86154
Previously we didn't compact ObjectGroups, but doing this would hopfully unlock more memory savings in bug 1654853.
Most of the trickiness here comes from accessing objects whose object group is forwarded, so require special-case handling to get their class, compartment etc.
Differential Revision: https://phabricator.services.mozilla.com/D86033
Previously we didn't compact ObjectGroups, but doing this would hopfully unlock more memory savings in bug 1654853.
Most of the trickiness here comes from accessing objects whose object group is forwarded, so require special-case handling to get their class, compartment etc.
Differential Revision: https://phabricator.services.mozilla.com/D86033
After the fix for bug 1642626, we need to detour `KERNELBASE!CloseHandle`
instead of K32's stub, which contains `JAE rel32`.
I also found a mistake in the fix for bug 1642626. When we put a conditional
jump in a trampoline, we need to reverse a condition, but the JAE case mistakenly
filled JAE straight. This patch corrects it to filling JB.
Differential Revision: https://phabricator.services.mozilla.com/D85477
CLOSED TREE
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
It is possible that some threads fail/forget to unregister themselves, in which case a registered thread id could get recycled by a later thread, which was not allowed before this patch.
Note: The thread name cannot currently be changed. We record a special marker with the new name, so the frontend could process it to split the thread track at that point.
We also record a marker when profiler_unregister_thread is called from an already-unregistered thread, this could help find reg/unreg mismatches or nesting in Firefox threads.
Differential Revision: https://phabricator.services.mozilla.com/D83293
On Linux (including Android), it was assumed that a registered thread could always be suspended through `tgkill`.
However in some cases a thread may not be correctly unregistered, in which case this would trigger `MOZ_ASSERT` or wait forever in the following loop.
This will especially be needed when `profiler_{,un}register_thread()` are made less strict in the following patch.
Windows and Mac already handle suspension failures.
Differential Revision: https://phabricator.services.mozilla.com/D83292
When the osclientcerts module attempts to use client certificates and keys from
certain tokens, the Windows APIs will attempt to load asepkcs.dll. If Firefox
blocks this library, the keys won't be available. Thus, it needs to be
unblocked.
Due to the architecture of osclientcerts (namely, its dedicated single thread),
using asepkcs.dll via the Windows APIs shouldn't cause the crashes that led to
this module being blocked.
Differential Revision: https://phabricator.services.mozilla.com/D82788
The file defines symbol renames to perform when linking. The list of
symbols to rename varies between an empty list and a full list depending
whether MOZ_MEMORY is set. Practically speaking, the variant with an
empty list is equivalent to not using a def-file at all.
This means we don't need to preprocess it any more, and we can just not
use a def-file when MOZ_MEMORY is not set.
As a side effect, this removes a rule from a Makefile.in.
Differential Revision: https://phabricator.services.mozilla.com/D83034
`nscore.h` includes `xpcom-config.h` which need not be generated for
non-XPCOM consumers. In additon, `nullptr` and `bool` are C++
keywords, so at least some of the comments were dated.
The added include lines address transitive consumers of `nscore.h`.
Differential Revision: https://phabricator.services.mozilla.com/D82640
This requires a workaround for the use of __wrap_dladdr, which can't be
used in logalloc-replay. The workaround involves making __wrap_dladdr
expand to dladdr, but that makes the definition ElfLinker.h conflict
with the one in the Android system headers, so we change it to match,
and adjust ElfLinker.cpp accordingly.
And while here, fix the condition in mozglue/misc to match the condition
around including Linker.h in StackWalk.cpp itself.
Differential Revision: https://phabricator.services.mozilla.com/D82648
To avoid deadlocks between the buffer main mutex and the externally-provided update callback code, the callback storage is now using a separate mutex, and both mutexes are never held at the same time.
Differential Revision: https://phabricator.services.mozilla.com/D82141
This is a rebase of a 7-year-old patch that was r=taras. Back then it
was waiting for breakpad changes that never were reviewed. However,
since then, bug 1486524 made the linker always map uncompressed files
directly, making it less necessary to report the library mappings to
the crash reporter, and bug 1291377 disabled the linker altogether on
Android 6.0+, which makes report_mapping unused at all in that case.
Differential Revision: https://phabricator.services.mozilla.com/D81025
AVG AntiVirus hooks ntdll!NtMapViewOfSection by planting two JMP instructions,
jumping to a trampoline area first, then jumping to aswhook.dll.
```
ntdll!NtMapViewOfSection:
00007ffa`6d77c560 e9d33cfebf jmp 00007ffa`2d760238
00007ffa`2d760238 ff25f2ffffff jmp qword ptr [00007ffa`2d760230] --> 00007ffa`541e2ad0
aswhook+0x2ad0:
00007ffa`541e2ad0 4055 push rbp
00007ffa`541e2ad2 53 push rbx
00007ffa`541e2ad3 56 push rsi
```
With this patch, our detour can detour on top of that pattern. The first part is
to remove the MEM_IMAGE check from IsPageAccessible. The second part is to introduce
a loop in ResolveRedirectedAddress to resolve a chain of jumps.
Differential Revision: https://phabricator.services.mozilla.com/D81582
This patch moves the logics of jump detection from ResolveRedirectedAddress to
ReadOnlyTargetFunction to simplify ReadOnlyTargetFunction.
Differential Revision: https://phabricator.services.mozilla.com/D81580
The profiler can be "paused", which stops sampling, and since bug 1578329 stops markers as well.
Some test suites use pausing between tests (to better differentiate the tests, to keep the profiler ready to run, and to lower the amount of recorded data). But this causes problems with some tracing markers, as their matching ends have not been recorded (e.g., an end marker is missing), which show up as very loooong markers.
To solve this, we need to be able to pause sampling only, but keep recording markers.
But we still need to be able to pause the whole profiler, in particular before capturing, to avoid recording anything around that time.
This big patch is mostly mechanical changes: Wherever there are "Pause" and "Unpause/Resume" profiler functions, we add matching "PauseSampling" and "UnpauseSampling/ResumeSampling" functions that only impact the periodic sampling loop; And existing "Pause/Unpause/Resume" imply pausing sampling as well.
Exceptions and extra work:
- nsIProfiler (the JS API) already had `Pause/ResumeSampling()`, which misleadingly paused everything! Now they do the right thing, and we have `Pause/Resume()` as well.
- All tests using `Pause/ResumeSampling()` now use `Pause/Resume()`, except for Talos tests that only pause sampling between tests; Added some extra `Pause()` calls to pause everything before capturing profiles.
- GeckoJavaSampler doesn't handle pausing/resuming everything, this should be done in a follow-up bug.
- Sampling-only pauses are not streamed into JSON. If needed, we should follow-up, with potential work on the front-end to deal with these.
Differential Revision: https://phabricator.services.mozilla.com/D81492
This header is using `MOZ_RAII` and `MFBT_ABI` from `Attributes.h` and
`Types.h`, respectively, so it should include those headers.
Differential Revision: https://phabricator.services.mozilla.com/D81600
This is a data race, but I don't think it is causing problems at the moment. It will go away when we get rid of ObjectGroups and is not trivial to fix, hence the decision to suppress it.
Differential Revision: https://phabricator.services.mozilla.com/D81327
This was previously r=jchen and landed, but was backed out because some
Android tests were running on an unrealistically old Linux kernel. These
tests have been retired, so this can reland.
Differential Revision: https://phabricator.services.mozilla.com/D81278
Bug 1486524 disabled the features from the custom linker that required
AutoObjectMapperFaultyLib. We can now rely on AutoObjectMapperPOSIX
instead.
Differential Revision: https://phabricator.services.mozilla.com/D81264