terrafx / terrafx.interop.windows

Interop bindings for Windows.
MIT License
257 stars 31 forks source link

Manually provide MiniDumpWriteDump and MINIDUMP_TYPE enum for now. #398

Open AraHaan opened 2 months ago

AraHaan commented 2 months ago

Description (optional)

Currently ClangSharp skips generating these even though they are not explicitly excluded for some reason. As such until https://github.com/dotnet/ClangSharp/issues/571 is fixed I think it is best to provide them manually for now.

Rationale

Currently for developers, one must manually provide the function signature to MiniDumpWriteDump even if they already depend on TerraFX.Interop.Windows, this function signature will often times be directly copied from the internet and might use SafeProcessHandle, SafeFileHandle, etc which means no Windows.OpenProcess call for hProcess, and no Windows.OpenFile call for hFile. This then results in bloating up their codebase more than it should be just from interop code that should be in TerraFX.Interop.Windows by default. It also makes things overly more complex than it needs to be especially for simple usage.

Proposed API

The proposed API is as follows (enum values left out for impl PR):

namespace TerraFX.Interop.Windows;

[Flags]
public enum MINIDUMP_TYPE
{
    MiniDumpNormal,
    MiniDumpWithDataSegs,
    MiniDumpWithFullMemory,
    MiniDumpWithHandleData,
    MiniDumpFilterMemory,
    MiniDumpScanMemory,
    MiniDumpWithUnloadedModules,
    MiniDumpWithIndirectlyReferencedMemory,
    MiniDumpFilterModulePaths,
    MiniDumpWithProcessThreadData,
    MiniDumpWithPrivateReadWriteMemory,
    MiniDumpWithoutOptionalData,
    MiniDumpWithFullMemoryInfo,
    MiniDumpWithThreadInfo,
    MiniDumpWithCodeSegs,
    MiniDumpWithoutAuxiliaryState,
    MiniDumpWithFullAuxiliaryState,
    MiniDumpWithPrivateWriteCopyMemory,
    MiniDumpIgnoreInaccessibleMemory,
    MiniDumpWithTokenInformation,
    MiniDumpWithModuleHeaders,
    MiniDumpFilterTriage,
    MiniDumpWithAvxXStateContext,
    MiniDumpWithIptTrace,
    MiniDumpScanInaccessiblePartialPages,
    MiniDumpFilterWriteCombinedMemory,
    MiniDumpValidTypeFlags,
}

public static unsafe partial class Windows
{
    public static extern BOOL MiniDumpWriteDump(HANDLE hProcess, [NativeTypeName("DWORD")] uint ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, [NativeTypeName("PMINIDUMP_EXCEPTION_INFORMATION")] void* ExceptionParam, [NativeTypeName("PMINIDUMP_USER_STREAM_INFORMATION")] void* UserStreamParam, [NativeTypeName("PMINIDUMP_CALLBACK_INFORMATION")] void* CallbackParam);
}

Drawbacks

If a user wants to specify a non-null value for any of the last 3 params, they would need to manually create the types for them and then use them afterwards this would be because I would consider this advanced usage of the function and not basic usage with only passing null into them.

Alternatives

No alternatives was considered.

Discussions (optional)

https://github.com/terrafx/terrafx.interop.windows/pull/241 https://github.com/terrafx/terrafx.interop.windows/issues/240

tannergooding commented 2 months ago

As per https://github.com/dotnet/ClangSharp/issues/571 you need to explicitly handle each header, namely by adding the right files to handle um/mionidumpset.h here: https://github.com/terrafx/terrafx.interop.windows/tree/main/generation/Windows/um

AraHaan commented 1 month ago

As per dotnet/ClangSharp#571 you need to explicitly handle each header, namely by adding the right files to handle um/mionidumpset.h here: https://github.com/terrafx/terrafx.interop.windows/tree/main/generation/Windows/um

Alright added it manually, just need to figure out a way to exclude all of the types that clangsharp generates for MiniDumpWriteDump except for the MINIDUMP_TYPE enum.

I have already remapped those types in the function call to void*'s as well.

tannergooding commented 1 month ago

You shouldn’t exclude types like that. Typically whole headers are generated at once to avoid future breaks and potential issues

AraHaan commented 1 month ago

You shouldn’t exclude types like that. Typically whole headers are generated at once to avoid future breaks and potential issues

Sadly in the case of this header the MINIDUMP_CALLBACK_INFORMATION generates something that does not look like it compiles because it generates this:

// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

// Ported from um/xmllite.h in the Windows SDK for Windows 10.0.26100.0
// Original source is Copyright © Microsoft. All rights reserved.

using System.Runtime.InteropServices;

namespace TerraFX.Interop.Windows;

/// <include file='MINIDUMP_CALLBACK_INFORMATION.xml' path='doc/member[@name="MINIDUMP_CALLBACK_INFORMATION"]/*' />
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public unsafe partial struct MINIDUMP_CALLBACK_INFORMATION
{
    /// <include file='MINIDUMP_CALLBACK_INFORMATION.xml' path='doc/member[@name="MINIDUMP_CALLBACK_INFORMATION.CallbackRoutine"]/*' />
    [NativeTypeName("MINIDUMP_CALLBACK_ROUTINE")]
    public delegate* unmanaged<void*, MINIDUMP_CALLBACK_INPUT*, MINIDUMP_CALLBACK_OUTPUT*, BOOL> CallbackRoutine;

    /// <include file='MINIDUMP_CALLBACK_INFORMATION.xml' path='doc/member[@name="MINIDUMP_CALLBACK_INFORMATION.CallbackParam"]/*' />
    [NativeTypeName("PVOID")]
    public void* CallbackParam;
}

Ironically this can compile easily without anything except the Windows class containing the MiniDumpWriteDump method, the MINIDUMP_TYPE enum, and the MINIDUMP_EXCEPTION_INFORMATION & MINIDUMP_EXCEPTION_INFORMATION64 structures.

AraHaan commented 1 month ago

Ah I see, it's a warning that gets displayed as an error in Visual Studio.

AraHaan commented 1 month ago
terrafx.interop.windows\sources\Interop\Windows\Windows\um\minidumpapiset\MINIDUMP_THREAD_CALLBACK.cs(19,20): error CS0723: Cannot declare a variable of static type 'CONTEXT'
terrafx.interop.windows\sources\Interop\Windows\Windows\um\minidumpapiset\MINIDUMP_THREAD_EX_CALLBACK.cs(19,20): error CS0723: Cannot declare a variable of static type 'CONTEXT'

I guess time to try nint for it 😄.

tannergooding commented 1 month ago

Sadly in the case of this header the MINIDUMP_CALLBACK_INFORMATION generates something that does not look like it compiles because it generates this:

What is causing it to fail to compile?

I guess time to try nint for it 😄.

void* should be used in such cases. CONTEXT in general is tricky because there isn't a singular definition, there is a completely different type per architecture (such as AMD64_NT_CONTEXT or ARM64_NT_CONTEXT).