Add barebones of MiMalloc WinDbg extension

This commit is contained in:
Gustavo Varo 2025-03-04 08:57:24 -05:00
parent 632fe6d8c8
commit a6302f4768
6 changed files with 173 additions and 3 deletions

View file

@ -74,6 +74,10 @@ set(mi_sources
src/stats.c
src/prim/prim.c)
if(WIN32 AND MI_WIN_DBG_EXTS)
list(APPEND mi_sources src/prim/windows/windbg/mimalloc_dbg.cpp)
endif()
set(mi_cflags "")
set(mi_cflags_static "") # extra flags for a static library build
set(mi_cflags_dynamic "") # extra flags for a shared-object library build
@ -255,6 +259,17 @@ if(MI_TRACK_ETW)
endif()
endif()
if(MI_WIN_DBG_EXTS)
if(NOT WIN32)
set(MI_WIN_DBG_EXTS OFF)
message(WARNING "Can only enable Windows debbuger extension support on Windows (MI_WIN_DBG_EXTS=OFF)")
endif()
if(MI_WIN_DBG_EXTS)
message(STATUS "Compile with Windows debbuger extension support (MI_WIN_DBG_EXTS=ON)")
list(APPEND mi_defines MI_WIN_DBG_EXTS=1)
endif()
endif()
if(MI_GUARDED)
message(STATUS "Compile guard pages behind certain object allocations (MI_GUARDED=ON)")
list(APPEND mi_defines MI_GUARDED=1)

View file

@ -211,8 +211,7 @@
<Lib>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>
</AdditionalDependencies>
<AdditionalDependencies>dbgeng.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
@ -477,6 +476,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64EC'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\prim\windows\windbg\mimalloc_dbg.cpp" />
<ClCompile Include="..\..\src\random.c" />
<ClCompile Include="..\..\src\os.c" />
<ClCompile Include="..\..\src\stats.c" />
@ -493,6 +493,7 @@
<ClInclude Include="..\..\include\mimalloc\track.h" />
<ClInclude Include="..\..\include\mimalloc\types.h" />
<ClInclude Include="..\..\src\bitmap.h" />
<ClInclude Include="..\..\src\prim\windows\windbg\mimalloc_dbg.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -61,6 +61,9 @@
<ClCompile Include="..\..\src\arena-meta.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\prim\windows\windbg\mimalloc_dbg.cpp">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\mimalloc\atomic.h">

View file

@ -208,7 +208,7 @@
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;dbgeng.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>
@ -441,6 +441,7 @@
<ClInclude Include="..\..\include\mimalloc\track.h" />
<ClInclude Include="..\..\include\mimalloc\types.h" />
<ClInclude Include="..\..\src\bitmap.h" />
<ClInclude Include="..\..\src\prim\windows\windbg\mimalloc_dbg.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\alloc-aligned.c">
@ -506,6 +507,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64EC'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\prim\windows\windbg\mimalloc_dbg.cpp" />
<ClCompile Include="..\..\src\random.c" />
<ClCompile Include="..\..\src\stats.c" />
</ItemGroup>

View file

@ -61,6 +61,9 @@
<ClCompile Include="..\..\src\arena-meta.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\prim\windows\windbg\mimalloc_dbg.cpp">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\mimalloc\atomic.h">

View file

@ -0,0 +1,146 @@
/* ----------------------------------------------------------------------------
Copyright (c) Microsoft Research
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
#include <atomic>
#include <DbgEng.h>
#include <map>
#include <string>
#include <vector>
#include <Windows.h>
#include "mimalloc.h"
#include "mimalloc/internal.h"
ULONG64 g_MiMallocBase = 0;
IDebugClient* g_DebugClient = nullptr;
IDebugControl* g_DebugControl = nullptr;
IDebugSymbols3* g_DebugSymbols = nullptr;
IDebugDataSpaces* g_DataSpaces = nullptr;
// Function to find mimalloc.dll base address at startup
HRESULT FindMimallocBase()
{
if (g_DebugSymbols == nullptr)
{
return E_FAIL;
}
return g_DebugSymbols->GetModuleByModuleName("mimalloc", 0, NULL, &g_MiMallocBase);
}
// Entry point for the extension
extern "C" __declspec(dllexport) HRESULT CALLBACK DebugExtensionInitialize(PULONG version, PULONG flags)
{
UNREFERENCED_PARAMETER(flags);
// Ensure Version is valid
if (!version)
{
return E_INVALIDARG;
}
// Set the version
*version = DEBUG_EXTENSION_VERSION(1, 0);
HRESULT hr = DebugCreate(__uuidof(IDebugClient), (void**)&g_DebugClient);
if (FAILED(hr))
{
return hr;
}
// Query for the IDebugControl interface
hr = g_DebugClient->QueryInterface(__uuidof(IDebugControl), (void**)&g_DebugControl);
if (FAILED(hr))
{
g_DebugClient->Release();
return hr;
}
hr = g_DebugClient->QueryInterface(__uuidof(IDebugSymbols3), (void**)&g_DebugSymbols);
if (FAILED(hr))
{
g_DebugControl->Release();
g_DebugClient->Release();
return hr;
}
hr = g_DebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (void**)&g_DataSpaces);
if (FAILED(hr))
{
g_DebugSymbols->Release();
g_DebugControl->Release();
g_DebugClient->Release();
return hr;
}
// Find mimalloc base address at startup
hr = FindMimallocBase();
if (FAILED(hr) || g_MiMallocBase == 0)
{
return E_FAIL; // Prevent extension from loading
}
mi_register_output(
[](const char* msg, void* arg) {
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, msg);
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "\n");
},
nullptr);
g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, "mimalloc.dll base address found: 0x%llx\n", g_MiMallocBase);
return S_OK;
}
// Notifies the extension that a debug event has occurred
extern "C" __declspec(dllexport) void CALLBACK DebugExtensionNotify(ULONG notify, ULONG64 argument)
{
UNREFERENCED_PARAMETER(notify);
UNREFERENCED_PARAMETER(argument);
}
// Uninitializes the extension
extern "C" __declspec(dllexport) void CALLBACK DebugExtensionUninitialize()
{
if (g_DebugSymbols)
{
g_DebugSymbols->Release();
g_DebugSymbols = nullptr;
}
if (g_DebugControl)
{
g_DebugControl->Release();
g_DebugControl = nullptr;
}
if (g_DebugClient)
{
g_DebugClient->Release();
g_DebugClient = nullptr;
}
}
// Sample command: !mi_help
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_help(PDEBUG_CLIENT Client, PCSTR args)
{
UNREFERENCED_PARAMETER(args);
// Print Help
g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, "Hello from MiMalloc WinDbg Extension!\n");
return S_OK;
}
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_arenas(PDEBUG_CLIENT client, PCSTR args)
{
mi_debug_show_arenas();
return S_OK;
}