CsWin32: When not targeting specific CPU archetecture the ExceptionPointers member of MINIDUMP_EXCEPTION_INFORMATION can be IntPtr (or nint).
I use AnyCPU and I have it generate MiniDumpWriteDump and use the GetExceptionPointers() function on the runtime to get the exception pointers as an nint (IntPtr) and as such I wanted to avoid the cast entirely (I hate casts from 1 pointer type to another as it requires unsafe).
I even tried doing:
namespace Windows.Win32.System.Diagnostics.Debug
{
using global::System;
using Windows.Win32.Foundation;
/// <summary>Contains the exception information written to the minidump file by the MiniDumpWriteDump function.</summary>
/// <remarks>
/// <para><see href = "https://docs.microsoft.com/windows/win32/api//minidumpapiset/ns-minidumpapiset-minidump_exception_information">Learn more about this API from docs.microsoft.com</see>.</para>
/// </remarks>
internal struct MINIDUMP_EXCEPTION_INFORMATION : IEquatable<MINIDUMP_EXCEPTION_INFORMATION>
{
/// <summary>The identifier of the thread throwing the exception.</summary>
internal uint ThreadId;
/// <summary>
/// <para>A pointer to an <a href = "https://docs.microsoft.com/windows/desktop/api/winnt/ns-winnt-exception_pointers">EXCEPTION_POINTERS</a> structure specifying a computer-independent description of the exception and the processor context at the time of the exception.</para>
/// <para><see href = "https://docs.microsoft.com/windows/win32/api//minidumpapiset/ns-minidumpapiset-minidump_exception_information#members">Read more on docs.microsoft.com</see>.</para>
/// </summary>
internal nint ExceptionPointers;
/// <summary>Determines where to get the memory regions pointed to by the <b>ExceptionPointers</b> member. Set to <b>TRUE</b> if the memory resides in the process being debugged (the target process of the debugger). Otherwise, set to <b>FALSE</b> if the memory resides in the address space of the calling program (the debugger process). If you are accessing local memory (in the calling process) you should not set this member to <b>TRUE</b>.</summary>
internal BOOL ClientPointers;
public bool Equals(MINIDUMP_EXCEPTION_INFORMATION other)
=> throw new NotImplementedException();
public override bool Equals(object obj)
=> obj is MINIDUMP_EXCEPTION_INFORMATION minidumpExceptionInformation
&& this.Equals(minidumpExceptionInformation);
public override int GetHashCode()
=> throw new NotImplementedException();
}
}
But it resulted in it trying to generate that type anyway despite it being present in the project manually, as such it seems the only option is to have a version in the metadata that uses nint or IntPtr for that member instead. This is because it’s safe for me to target AnyCPU as I just get that data directly from the runtime and I do not mess with it further.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 16 (16 by maintainers)
And I still say
IntPtris the real “unsafe.” It’s just as risky but also opts out of type checking.Generated files usually have a
.g.csextension.@AArnott
Pack = 4is fine for both architectures in this case. It is basically a no-op for x86 since the default Pack is 4 but is required for 64-bit. On 64-bit, withoutPack = 4theExceptionPointersfield will be aligned on an 8 byte boundary and thus an extra 4 bytes inserted betweenThreadIdandExceptionPointers. Unfortunately this does make theExceptionPointersfield unnaturally aligned for a 64-bit machine but that is how it is defined in theDbgHelp.h. The definition above should be compatible with AnyCPU.A quick note on the
unsafekeyword in .NET Core 3.1 and .NET 5+. Using any API that returns or accepts anIntPtris inherently “unsafe”. Theunsafekeyword is a C# thing and has no impact on the generated code in any way so it really is a matter of preference. I personally prefer specifying the type precisely but there are many companies with constraints on puttingAllowUnsafeBlocksin projects so occasionally it is easier to useIntPtrbut it is all window dressing at this point in the .NET world.