-
Notifications
You must be signed in to change notification settings - Fork 134
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
COM marshalling E2E #2618
Comments
This is an interesting case - thanks for bringing it up @MichalStrehovsky. I think we should see why it doesn't hit the runtime block for number 3 above. I'm not 100%, but I think I agree with 1 and 2 as well. It's a special case, because we have special warning/code for this in the linker/analyzer. Most other feature switches work such that if the feature is off, there won't be any warning, and if it's on, that will bring in code which has RUC on it, and thus produce a warning. The special case for COM should ideally behave the same - especially since there are other COM entry points which do follow the typical feature switch/RUC pattern, so the current experience is inconsistent. That said - the difference in this case is that the runtime doesn't consistently fail. So if we can fix that and make the runtime consistently fail -> we should disable the warnings. But if we can't make the runtime consistently fail, I think it's better to keep the warnings. Just curious: You chose |
Agreed - my shallow expectation is that this should have failed without trimming too, but maybe I'm missing something.
Yes, that was just me being lazy to come up with a proper p/invoke. A null object reference marshals into a null pointer and Marshalling null interfaces is a real world scenario though because e.g. empty WinForms app goes through a similar codepath (dotnet/corert#8128 was all COM support we had to implement to make empty WinForms app work with NativeAOT back in the day). |
@LakshanF could you please take a look why this doesn't trigger the runtime failure? |
I see 2 separate issues here;
For 1), the trimming behavior is the same as " For 2), I can see us being consistent with other feature switches as @vitek-karas advocates above. Perhaps a mechanism for us to convey to the developer that they are using a feature that is not supported in runtime. In the specific case above, the failure likely happen since the COM types not getting loaded when the feature is switched off causes downstream failures before better error handling like ones here comes into effect. |
Personally I don't mind that the trimmed app is crashing - we provided enough warnings in that case. |
I don't think we block all COM paths in managed and native code if |
I know that we don't block all COM paths, but I thought it was a "best effort" kind of thing. In which case it would be interesting if we could block this case... |
Given that the non-trimmed behavior (no PublishTrimmed in the project file) is as above, it seems better to modify the warning behavior |
It is definitely possible to address this, but it isn't clear how best to do it without littering the COM enable check all over. The problem is lookup for marshallers of type I personally don't think this is worth fixing. I agree with the sentiment it is a best effort and as we dig deeper into the marshalling logic this is just going to get more complicate with more complex conditional checks. I accept this can be confusing but I think the multitude of warnings should be sufficient to say "Hey! You are doing something that will break here". Either we believe warnings are useful and users should respect them or we make sure the runtime fails in all cases and relax our warnings, requiring both seems a bit like busy work. |
Sounds good to me. If it's too complex, that would also mean it's complex to explain to the users, which is not ideal. In that case I favor the clear warning, which basically says "It's probably wrong". I think COM is sort of special in this case because of its complexity and spread through the runtime. Other features should be much clearer to cut off, and thus should provide a more consistent experience. Let me turn this argument around: If we try to disable the warnings... when would that be OK? My understanding is that such condition would be really complicated. So again - not worth it. |
Agree.
I don't think so. This is because of the contract of |
I've hit this in a test for ComWrappers: https://github.com/dotnet/runtime/blob/06228c10873ecec58c38cda58d7eb06f6b55e41b/src/tests/nativeaot/SmokeTests/ComWrappers/ComWrappers.csproj#L7-L8 The warning seems incorrect because the test is actually already following our guidelines for trimming safety - they register a COM wrapper, but they still get a warning. If we keep generating the warning, people will have to suppress them in addition to enabling ComWrappers. That's an annoyance. If we don't generate the warning, we should ideally have the same behavior before/after trimming. If things work before trimming but fail after, it's again one of the things that go against the spirit of safe trimming. Can we add a chokepoint at the spot where we try to look for |
The reason this is still failing is |
I think the current behavior in compiler warning is a good enough response to a challenging situation. As mentioned above, built-in-COM support is spread all over the code base. It is challenging to turn off the feature completely since there is also an inconsistent approach between managed (dynamic) and native (static) guards against the feature. We have the following 3 situations now:
There are inconsistencies between 2) and 3) above and the biggest concern is a dangerous COM slipping though in trimmed mode due to Discrepancy in Windows built-in COM support between native and managed sides. There have been some surgical fixes in native code that seems to mostly address this (e.g. see the fix for TypeBuilder.CreateType doesn't work on Windows in a trimmed app due to BuiltInComInterop being disabled) In this particular issue, there is a non-dangerous COM API not failing in 2) during runtime. Although not very consistent, the compiler time warning and runtime failure in trimmed mode seem both a reinforcement of the feature not present ("No means No") during runtime and some hints during compiler time that the developer is using a turned off feature. |
Ah, I see - I thought COM being disabled would route things through ComWrappers, but the warning makes sense if that's not the case. If there's a warning, we can have a behavioral difference. It feels like it would nice if disabled COM rerouted things to ComWrappers because it gives a chance to turn trimming unfriendly code into trimming friendly code, but it's one of those things where one is trying to make code they don't own trimming friendly. If we offer such last-ditch workaround mechanism, library developers will take it as an excuse to not make their libraries trimming friendly. So maybe we shouldn't have it. |
I ran into this on NativeAOT, but there's a gap with illink as well:
Repro
Observed behaviors
dotnet run
This prints
And then pops the dialog box.
dotnet publish
Prints the message from both the analyzer and illink. Then it crashes with:
Issues
dotnet run
scenario from finishing within the runtime? It would avoid the hard failure in dotnet publish.Cc @LakshanF @vitek-karas
The text was updated successfully, but these errors were encountered: