-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Startup hooks support in Mono #80391
Conversation
src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml
Outdated
Show resolved
Hide resolved
6acc15b
to
43a46d6
Compare
The mono changes look ok to me. |
Linked size shouldn't be affected. Unless you set Startup time might be affected a little bit because of the |
43a46d6
to
d9aa47c
Compare
d9aa47c
to
25344c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CoreLib changes look good.
Curious about the trimming story - in CoreCLR we simply don't support startup hooks with trimming. But this seems to make some effort to do that in mono. The problem is that startup hooks are effectively plugins, and so with trimmed framework the plugins may break. |
The primary use case for mobile right now is to allow hot reload to inject an agent into the app. Injecting the hook is actually a pretty static operation - the agent assembly has to make it into the app bundle that gets uploaded to the device or emulator - so there is a PackageReference, the StartupHookSupport SDK property is toggled (which toggles the feature flag), etc. So everything should be visible to the trimmer if it even runs (in Debug configurations the trimmer won't be trimming anything). The only other trimming that is happening is the initial trimming of System.Private.CoreLib when we create the runtime packs. At that stage we say that runtime hook switch defaults to true and we add the process hooks function to the linker descriptor so it's kept around. It's possible that we drop some private CoreLib APIs that a startup hook may want to use that are otherwise completely unused in the runtime and aren't in the linker descriptor. That's always a risk with private reflection. In general, I think any sort of more dynamic startup hook injection is unlikely to work on mobile. There's really no good way to get code onto a device without it being part of the app bundle. But running code before the user (or platform) code starts running is still useful. |
The event tracing failures on osx-x64 repro locally. Not sure how they're related but I'm sure it'll be educational... |
@lateralusX @dotnet/dotnet-diag So believe it or not the failure I'm seeing is due to the call in Questions:
|
No, that doesn't sound like a desired behavior to me. I don't see any reason that RuntimeEventSource should be conditional on having startup hooks enabled. I'm guessing what happened is that someone noticed it was important to initialize RuntimeEventSource prior to running startup hooks, and then separately someone else added an option to disable startup hooks and didn't recognize that the RuntimeEventSource.Initialize() should not be included in the scope of code that gets disabled. I'd propose we hoist the call to RuntimeEventSource.Initialize() outside the ProcessStartupHooks call. |
So change this to something more generic and call both the RuntimeEventSource initialization and the startup hook initialization from there? runtime/src/coreclr/vm/assembly.cpp Lines 1424 to 1437 in 210a7a9
|
Yeah, that sounds good to me. Perhaps something like: void ManagedStartup() // call this from native runtime startup code
{
InitBeforeUserCode(); // run EventSource initialize in here
ProcessStartupHooks(); // do the rest of the pre-existing startup hook logic here
} |
Hmm... that's actually not very linker friendly. Ideally I'd like to trim I guess the other way to go here is to make coreclr more like mono: call the |
Okay, CoreCLR now follows Mono's model: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mono bits LGTM!
On Mono the method is called from ep_rt_mono_init_finish and also from StartupHookProvider.ProcessStartupHooks. CoreCLR only calls it from StartupHookProvider. So if startup hooks are disabled, the runtime event source is also disabled.
This reverts commit 07219db97e736bd49111dff8a605550909386b12.
…nishInitialize Decouple eventpipe initialization from startup hooks. Previously if startup hooks were disabled, the runtime event source would not be initialized.
Also move the call out of EventPipeAdapter, back to ExecuteMainMethod. EventSource is independent of EventPipe (for example if ETL is used, or lttng)
A common configuration for coreclr is event source enabled, startup hooks disabled, so at least one managed call is inevitable. Since we have to call into managed no matter what, let the trimmer determine what happens once we get there. This is different from mono where published trimmed apps may have both startup hooks and event source disabled. In that case we would rather avoid a managed call to an empty method early in startup.
10ea4de
to
3fddf4f
Compare
CoreCLR I think this is ready to merge |
linux-arm64 llvmfullaot timeout is known #80805 |
…dotnet#80391) Fixes dotnet#47462 **CoreCLR** This also makes some changes to CoreCLR to decouple EventPipe and startup hooks. Presently if startup hooks are disabled, `RuntimeEventSource.Initialize` is never called. The PR makes the two features independent by moving runtime event source initialization out of the startup hook feature check. * Implement startup hooks support in Mono * Keep StartupHookProvider.ProcessStartupHooks under feature flag * Don't catch/cleanup the exceptions from startup hooks. * Add an ios simulator startup hook functional test * Implement Android functional test * Add WASM functional test * Make a single managed startup method for CoreCLR A common configuration for coreclr is event source enabled, startup hooks disabled, so at least one managed call is inevitable. Since we have to call into managed no matter what, let the trimmer determine what happens once we get there. This is different from mono where published trimmed apps may have both startup hooks and event source disabled. In that case we would rather avoid a managed call to an empty method early in startup. * fix build and line damage
Fixes #47462
CoreCLR This also makes some changes to CoreCLR to decouple EventPipe and startup hooks. Presently if startup hooks are disabled,
RuntimeEventSource.Initialize
is never called. The PR makes the two features independent by moving runtime event source initialization out of the startup hook feature check.TODO: