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
IntPtr
is the real “unsafe.” It’s just as risky but also opts out of type checking.Generated files usually have a
.g.cs
extension.@AArnott
Pack = 4
is 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 = 4
theExceptionPointers
field will be aligned on an 8 byte boundary and thus an extra 4 bytes inserted betweenThreadId
andExceptionPointers
. Unfortunately this does make theExceptionPointers
field 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
unsafe
keyword in .NET Core 3.1 and .NET 5+. Using any API that returns or accepts anIntPtr
is inherently “unsafe”. Theunsafe
keyword 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 puttingAllowUnsafeBlocks
in projects so occasionally it is easier to useIntPtr
but it is all window dressing at this point in the .NET world.