Turn off AMSI member invocation on *nix release builds#24451
Conversation
|
|
||
| internal static void LogMemberInvocation(string targetName, string name, object[] args) | ||
| { | ||
| #if UNIX && !DEBUG |
There was a problem hiding this comment.
Thanks for tackling this, but, given that there seems to be only one call to this method (in Binders.cs), wouldn't it be better for performance reasons to conditionally exclude that call instead?
There was a problem hiding this comment.
Nah the JIT should optimize it out
There was a problem hiding this comment.
It should have, but ... does it and at what point (interpreter)?
There was a problem hiding this comment.
Taking a closer look at the call site, it seems that a (cached) reference to the method is being passed as an argument to another method, and it's not clear to me how that could be optimized away (but I'm not familiar with the subtleties of JIT compilation), especially since it seems desirable to prevent that other method call altogether.
PowerShell/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
Lines 6946 to 6958 in 623c451
There was a problem hiding this comment.
@mklement0 The code you referenced does only one thing - call LogMemberInvocation method. This is the code that should have been excluded.
There was a problem hiding this comment.
Ah, of course, thanks. I agree.
There was a problem hiding this comment.
The reason why I put the change here is in case the method is called in multiple places in the future. I can certainly change it so the expression tree doesn't call it but I'm not sure if there is any actual overhead to care about with just calling a method that is ultimately a no-op. Will defer to the pwsh team to see what they decide here.
There was a problem hiding this comment.
Thanks, Jordan. I suppose a pragmatic way to handle this would be to to use #if UNIX && !DEBUG around both the currently known only call site as well as inside the method.
There was a problem hiding this comment.
So the more I think about this the more I think it would be better to make a new method in the compiler to conditionally add this expression. The JIT should optimize the call, but it won't optimize the array creation for the argument and extra boxing involved. Should be very minimal, but might as well get rid of it if we can.
Something like this:
private Expression MaybeAddMemberInvocationLogging(Expression expr, Expression[] args, ...otherNeededState)
{
#if UNIX && !DEBUG
return expr;
#else
return Expression.Block(
Expression.Call(
CachedReflectionInfo.MemberInvocationLoggingOps_LogMemberInvocation,
Expression.Constant(targetName),
Expression.Constant(name),
Expression.NewArrayInit(
typeof(object),
args.Select(static e => e.Expression.Cast(typeof(object))))),
expr);
#endif
}There was a problem hiding this comment.
Updated to follow this pattern.
SeeminglyScience
left a comment
There was a problem hiding this comment.
Feel free to ping me on discord when the changes are made (or you've otherwise responded) and I'll get this merged. Thanks Jordan! ❤️
Turn off the AMSI member invocation logging for non-Windows release builds. This is slightly more efficient as there's no extra work to create the AMSI string.
SeeminglyScience
left a comment
There was a problem hiding this comment.
LGTM! Thank you Jordan!
|
📣 Hey @jborean93, how did we do? We would love to hear your feedback with the link below! 🗣️ 🔗 https://aka.ms/PSRepoFeedback |
| typeof(object), | ||
| args.Select(static e => e.Expression.Cast(typeof(object))))), | ||
| expr); | ||
| MaybeAddMemberInvocationLogging(expr, targetName, name, args); |
There was a problem hiding this comment.
I may be missing something, but it looks like the return value from this method call is never used; shouldn't that be expr = MaybeAddMemberInvocationLogging(expr, targetName, name, args);?
There was a problem hiding this comment.
Good pickup, sorry for missing that. @SeeminglyScience will be submitting a new PR to fix that.
There was a problem hiding this comment.
That says there are no tests.
And many would say thank you for such an omission 😄
PR Summary
Turn off the AMSI member invocation logging for non-Windows release builds. This is slightly more efficient as there's no extra work to create the AMSI string.
Fixes: #21492
PR Context
#21492 (comment)
It doesn't make sense for this feature to be on for a proper release build as writing to stdout will affect anything calling PowerShell. The env var name also indicates this is an internal optional and not a publicly supported feature so shouldn't be under any API contract.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.- [ ] Issue filed:
(which runs in a different PS Host).