Skip to content
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

PowerShell 7 (32bit) Crash on Get-Counter '\Memory\Available MBytes' #13829

Closed
jmiller76 opened this issue Oct 21, 2020 · 2 comments
Closed

PowerShell 7 (32bit) Crash on Get-Counter '\Memory\Available MBytes' #13829

jmiller76 opened this issue Oct 21, 2020 · 2 comments
Assignees
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Release-Testing WG-Cmdlets general cmdlet issues

Comments

@jmiller76
Copy link

Steps to reproduce

Windows Server 2016 -1607 14393.3986
and
Microsoft Windows 10.0.19041

both with.
PowerShell-7.0.3-win-x86

	Get-Counter '\Memory\Available MBytes'

interesting enough:

pwsh -command {Get-Counter '\Memory\Available MBytes'}
called from CMD does not seem to generate a visible stacktrace.

Expected behavior

Result or Error (if the command is not supported in 32bit.)

Actual behavior

Fatal error. Internal CLR error. (0x80131506)                                                                              at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr, System.Object, Boolean)                          at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr, System.Type)                                     at System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr, System.Type)                                           at Microsoft.Powershell.Commands.GetCounter.PdhNative.PdhHelper.GetCounterInfoPlus(IntPtr, UInt32 ByRef, UInt32 ByRef, UInt64 ByRef)                                                                                                            at Microsoft.Powershell.Commands.GetCounter.PdhNative.PdhHelper.ReadNextSet(Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet ByRef, Boolean)                                                                                at Microsoft.PowerShell.Commands.GetCounterCommand.ProcessGetCounter()                                                  at Microsoft.PowerShell.Commands.GetCounterCommand.EndProcessing()                                                      at System.Management.Automation.Cmdlet.DoEndProcessing()                                                                at System.Management.Automation.CommandProcessorBase.Complete()                                                         at System.Management.Automation.CommandProcessorBase.DoComplete()                                                       at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)                                                                                                                    at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)                   at System.Management.Automation.PipelineOps.InvokePipeline(System.Object, Boolean, System.Management.Automation.CommandParameterInternal[][], System.Management.Automation.Language.CommandBaseAst[], System.Management.Automation.CommandRedirection[][], System.Management.Automation.Language.FunctionContext)                                                       at System.Management.Automation.Interpreter.ActionCallInstruction`6[[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Run(System.Management.Automation.Interpreter.InterpretedFrame)                                                             at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)                                                                                                      at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)                                                                                                      at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)                                                                                                                          at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon)                                                   at System.Management.Automation.DlrScriptCommandProcessor.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)                                                                       at System.Management.Automation.DlrScriptCommandProcessor.Complete()                                                    at System.Management.Automation.CommandProcessorBase.DoComplete()                                                       at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)                                                                                                                    at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)                   at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()                                                  at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()                                              at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProcImpersonate()                                   at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()                                                   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)                                                     at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)                                                                                                            at System.Threading.ThreadHelper.ThreadStart()                               

We found this because someone manually installed 32bit PowerShell. Windows 10 copy was from the Zip download 2016 server was from the MSI. (Stacktrace above on Windows 10 laptop)

@jmiller76 jmiller76 added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label Oct 21, 2020
@jmiller76
Copy link
Author

ewww, that stack trace looks worse in rendered markdown then it was in the preview. it was a simple reproduce on laptop, but if needed, I can provide more info.

@SeeminglyScience
Copy link
Collaborator

SeeminglyScience commented Oct 21, 2020

Looks like the problem is in how the PDH_COUNTER_INFO struct is defined here:

//
// This is the structure returned by PdhGetCounterInfo().
// We only need dwType and lDefaultScale fields from this structure.
// We access those fields directly. The struct is here for reference only.
//
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
private struct PDH_COUNTER_INFO
{
[FieldOffset(0)] public UInt32 dwLength;
[FieldOffset(4)] public UInt32 dwType;
[FieldOffset(8)] public UInt32 CVersion;
[FieldOffset(12)] public UInt32 CStatus;
[FieldOffset(16)] public UInt32 lScale;
[FieldOffset(20)] public UInt32 lDefaultScale;
[FieldOffset(24)] public IntPtr dwUserData;
[FieldOffset(32)] public IntPtr dwQueryUserData;
[FieldOffset(40)] public string szFullPath;
[FieldOffset(48)] public string szMachineName;
[FieldOffset(56)] public string szObjectName;
[FieldOffset(64)] public string szInstanceName;
[FieldOffset(72)] public string szParentInstance;
[FieldOffset(80)] public UInt32 dwInstanceIndex;
[FieldOffset(88)] public string szCounterName;
[FieldOffset(96)] public string szExplainText;
[FieldOffset(104)] public IntPtr DataBuffer;
}

Using LayoutKind.Explicit doesn't work when the struct contains pointer type fields outside of the union. Here's an example of how it can be declared differently to work in 32 bit processes:

(Click to expand!)

using System;
using System.Runtime.InteropServices;

// Direct blittable struct translation. Needs edits if marshaling is desired (e.g. `string`)

[StructLayout(LayoutKind.Sequential)]
public unsafe struct PDH_COUNTER_INFO
{
    public uint dwLength;

    public uint dwType;

    public uint CVersion;

    public uint CStatus;

    public int lScale;

    public int lDefaultScale;

    public nuint dwUserData;

    public nuint dwQueryUserData;

    public char* szFullPath;

    public PdhDataUnion DataUnion;

    public char* szExplainText;

    public fixed uint DataBuffer[1];
}

[StructLayout(LayoutKind.Explicit)]
public unsafe struct PdhDataUnion
{
    [FieldOffset(0)]
    public PDH_DATA_ITEM_PATH_ELEMENTS DataItemPath;

    [FieldOffset(0)]
    public PDH_COUNTER_PATH_ELEMENTS CounterPath;

    [FieldOffset(0)]
    public OtherUnionMember UnionMember3;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct PDH_DATA_ITEM_PATH_ELEMENTS
{
    public char* szMachineName;

    public Guid ObjectGUID;

    public uint dwItemId;

    public char* szInstanceName;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct PDH_COUNTER_PATH_ELEMENTS
{
    public char* szMachineName;

    public char* szObjectName;

    public char* szInstanceName;

    public char* szParentInstance;

    public uint dwInstanceIndex;

    public char* szCounterName;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct OtherUnionMember
{
    public char* szMachineName;

    public char* szObjectName;

    public char* szInstanceName;

    public char* szParentInstance;

    public uint dwInstanceIndex;

    public char* szCounterName;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Release-Testing WG-Cmdlets general cmdlet issues
Projects
None yet
Development

No branches or pull requests

4 participants