mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 19:38:41 +03:00
Organize Functions into its own files
Add a clang style so the entire proejct can follow same style.
This commit is contained in:
parent
71549dae90
commit
0ced3c5216
11 changed files with 412 additions and 65 deletions
|
@ -5,74 +5,46 @@ 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);
|
||||
}
|
||||
#include "mimalloc_windbg_utils.h"
|
||||
|
||||
// Entry point for the extension
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK DebugExtensionInitialize(PULONG version, PULONG flags)
|
||||
{
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK DebugExtensionInitialize(PULONG version, PULONG flags) {
|
||||
UNREFERENCED_PARAMETER(flags);
|
||||
|
||||
// Ensure Version is valid
|
||||
if (!version)
|
||||
{
|
||||
if (!version) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Set the version
|
||||
*version = DEBUG_EXTENSION_VERSION(1, 0);
|
||||
|
||||
// Create the debug interfaces
|
||||
HRESULT hr = DebugCreate(__uuidof(IDebugClient), (void**)&g_DebugClient);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Query for the IDebugControl interface
|
||||
hr = g_DebugClient->QueryInterface(__uuidof(IDebugControl), (void**)&g_DebugControl);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
hr = g_DebugClient->QueryInterface(__uuidof(IDebugControl4), (void**)&g_DebugControl);
|
||||
if (FAILED(hr)) {
|
||||
g_DebugClient->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Query for the IDebugSymbols3 interface
|
||||
hr = g_DebugClient->QueryInterface(__uuidof(IDebugSymbols3), (void**)&g_DebugSymbols);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Release();
|
||||
g_DebugClient->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Query for the IDebugDataSpaces interface
|
||||
hr = g_DebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (void**)&g_DataSpaces);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
g_DebugSymbols->Release();
|
||||
g_DebugControl->Release();
|
||||
g_DebugClient->Release();
|
||||
|
@ -82,11 +54,11 @@ extern "C" __declspec(dllexport) HRESULT CALLBACK DebugExtensionInitialize(PULON
|
|||
|
||||
// Find mimalloc base address at startup
|
||||
hr = FindMimallocBase();
|
||||
if (FAILED(hr) || g_MiMallocBase == 0)
|
||||
{
|
||||
return E_FAIL; // Prevent extension from loading
|
||||
if (FAILED(hr) || g_MiMallocBase == 0) {
|
||||
return E_FAIL; // Prevent extension from loading
|
||||
}
|
||||
|
||||
// Register output callbacks
|
||||
mi_register_output(
|
||||
[](const char* msg, void* arg) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, msg);
|
||||
|
@ -94,43 +66,38 @@ extern "C" __declspec(dllexport) HRESULT CALLBACK DebugExtensionInitialize(PULON
|
|||
},
|
||||
nullptr);
|
||||
|
||||
// Print the mimalloc base address, this indicates extension was load successfully
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
extern "C" __declspec(dllexport) void CALLBACK DebugExtensionUninitialize() {
|
||||
if (g_DebugSymbols) {
|
||||
g_DebugSymbols->Release();
|
||||
g_DebugSymbols = nullptr;
|
||||
}
|
||||
|
||||
if (g_DebugControl)
|
||||
{
|
||||
if (g_DebugControl) {
|
||||
g_DebugControl->Release();
|
||||
g_DebugControl = nullptr;
|
||||
}
|
||||
|
||||
if (g_DebugClient)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Help command: !mi_help
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_help(PDEBUG_CLIENT Client, PCSTR args) {
|
||||
UNREFERENCED_PARAMETER(args);
|
||||
|
||||
// Print Help
|
||||
|
@ -139,8 +106,11 @@ extern "C" __declspec(dllexport) HRESULT CALLBACK mi_help(PDEBUG_CLIENT Client,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_arenas(PDEBUG_CLIENT client, PCSTR args)
|
||||
{
|
||||
mi_debug_show_arenas();
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_stats(PDEBUG_CLIENT client, PCSTR args) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_options(PDEBUG_CLIENT client, PCSTR args) {
|
||||
mi_options_print();
|
||||
return S_OK;
|
||||
}
|
75
src/prim/windows/windbg/mimalloc_windbg_arenas.cpp
Normal file
75
src/prim/windows/windbg/mimalloc_windbg_arenas.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
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 "mimalloc_windbg_utils.h"
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_arenas(PDEBUG_CLIENT client, PCSTR args) {
|
||||
UNREFERENCED_PARAMETER(args);
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ULONG64 subprocMainAddr = 0;
|
||||
hr = GetSymbolOffset("subproc_main", subprocMainAddr);
|
||||
if (FAILED(hr) || subprocMainAddr == 0) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Could not locate mi_subproc_t.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, "mi_subproc_t found at 0x%llx\n\n", subprocMainAddr);
|
||||
|
||||
mi_subproc_t subprocMain {};
|
||||
hr = ReadMemory(subprocMainAddr, &subprocMain, sizeof(mi_subproc_t));
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read mi_subproc_t at 0x%llx.\n", subprocMainAddr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Print results
|
||||
size_t arenaCount = subprocMain.arena_count.load();
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, "Arena count: %llu\n\n", arenaCount);
|
||||
|
||||
for (size_t i = 0; i < arenaCount; ++i) {
|
||||
ULONG64 arenaAddr = subprocMainAddr + offsetof(mi_subproc_t, arenas) + (i * sizeof(std::atomic<mi_arena_t*>));
|
||||
|
||||
// Print clickable Arena Index link
|
||||
g_DebugControl->ControlledOutput(DEBUG_OUTCTL_AMBIENT_DML, DEBUG_OUTPUT_NORMAL,
|
||||
"[0x%p] [<link cmd=\"!mi_dump_arena %p\">Arena %llu</link>]\n", (void*)arenaAddr, (void*)arenaAddr, i);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_arena(PDEBUG_CLIENT client, PCSTR args) {
|
||||
if (!args || !*args) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "Usage: !mi_dump_arena <arena_address>\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
ULONG64 arenaAddr = 0;
|
||||
if (sscanf_s(args, "%llx", &arenaAddr) != 1 || arenaAddr == 0) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Invalid arena address provided: %s\n", args);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, "Dumping Arena at Address: 0x%016llx\n\n", arenaAddr);
|
||||
|
||||
//// Read the `mi_arena_t` structure from the memory
|
||||
// mi_arena_t arena{};
|
||||
// HRESULT hr = ReadMemory(arenaAddr, &arena, sizeof(mi_arena_t));
|
||||
// if (FAILED(hr))
|
||||
//{
|
||||
// g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read mi_arena_t at 0x%016llx.\n", arenaAddr);
|
||||
// return hr;
|
||||
// }
|
||||
|
||||
// g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, " - Slice Count: %llu\n", arena.slice_count);
|
||||
// g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, " - Info Slices: %llu\n", arena.info_slices);
|
||||
// g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, " - NUMA Node: %d\n", arena.numa_node);
|
||||
// g_DebugControl->Output(DEBUG_OUTPUT_NORMAL, " - Exclusive: %s\n", arena.is_exclusive ? "Yes" : "No");
|
||||
//
|
||||
return S_OK;
|
||||
}
|
16
src/prim/windows/windbg/mimalloc_windbg_options.cpp
Normal file
16
src/prim/windows/windbg/mimalloc_windbg_options.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
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 "mimalloc_windbg_utils.h"
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT CALLBACK mi_dump_options(PDEBUG_CLIENT client, PCSTR args) {
|
||||
UNREFERENCED_PARAMETER(args);
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
return S_OK;
|
||||
}
|
118
src/prim/windows/windbg/mimalloc_windbg_utils.cpp
Normal file
118
src/prim/windows/windbg/mimalloc_windbg_utils.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
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 "mimalloc_windbg_utils.h"
|
||||
|
||||
ULONG64 g_MiMallocBase = 0;
|
||||
|
||||
IDebugClient* g_DebugClient = nullptr;
|
||||
IDebugControl4* 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);
|
||||
}
|
||||
|
||||
HRESULT GetSymbolOffset(const char* symbolName, ULONG64& outOffset) {
|
||||
// Ensure debug interfaces are valid
|
||||
if (!g_DebugSymbols || g_MiMallocBase == 0) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Construct the full symbol name: "mimalloc!<symbolName>"
|
||||
std::string fullSymbol = "mimalloc!";
|
||||
fullSymbol += symbolName;
|
||||
|
||||
// Retrieve the memory offset of the symbol in the debuggee process
|
||||
HRESULT hr = g_DebugSymbols->GetOffsetByName(fullSymbol.c_str(), &outOffset);
|
||||
if (FAILED(hr) || outOffset == 0) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to locate symbol: %s\n", fullSymbol.c_str());
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadMemory(const char* symbolName, void* outBuffer, size_t bufferSize) {
|
||||
if (!g_DataSpaces) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Step 1: Get the memory address of the symbol
|
||||
ULONG64 symbolOffset = 0;
|
||||
HRESULT hr = GetSymbolOffset(symbolName, symbolOffset);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Step 2: Read memory from the debuggee
|
||||
hr = g_DataSpaces->ReadVirtual(symbolOffset, outBuffer, bufferSize, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read memory for symbol: %s\n", symbolName);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadMemory(ULONG64 address, void* outBuffer, size_t bufferSize) {
|
||||
if (!g_DataSpaces) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Read memory directly from the given address
|
||||
HRESULT hr = g_DataSpaces->ReadVirtual(address, outBuffer, bufferSize, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read memory at address: 0x%llx\n", address);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReadString(const char* symbolName, std::string& outBuffer) {
|
||||
if (!g_DataSpaces) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Step 1: Get the memory address of the symbol (pointer to string)
|
||||
ULONG64 stringPtr = 0;
|
||||
HRESULT hr = ReadMemory(symbolName, &stringPtr, sizeof(ULONG64));
|
||||
if (FAILED(hr) || stringPtr == 0) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Symbol %s is NULL or invalid.\n", symbolName);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Step 2: Read the actual string data from the debuggee memory
|
||||
char tempChar = 0;
|
||||
size_t length = 0;
|
||||
|
||||
do {
|
||||
hr = g_DataSpaces->ReadVirtual(stringPtr + length, &tempChar, sizeof(char), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read string from address 0x%llx.\n", stringPtr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
length++;
|
||||
} while (tempChar != '\0');
|
||||
|
||||
outBuffer.resize(length);
|
||||
hr = g_DataSpaces->ReadVirtual(stringPtr, &outBuffer[0], length, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
g_DebugControl->Output(DEBUG_OUTPUT_ERROR, "ERROR: Failed to read string from address 0x%llx.\n", stringPtr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
32
src/prim/windows/windbg/mimalloc_windbg_utils.h
Normal file
32
src/prim/windows/windbg/mimalloc_windbg_utils.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
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.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MIMALLOC_WINDBG_UTILS_H
|
||||
#define MIMALLOC_WINDBG_UTILS_H
|
||||
|
||||
#include <DbgEng.h>
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mimalloc.h"
|
||||
#include "mimalloc/internal.h"
|
||||
|
||||
extern ULONG64 g_MiMallocBase;
|
||||
|
||||
extern IDebugClient* g_DebugClient;
|
||||
extern IDebugControl4* g_DebugControl;
|
||||
extern IDebugSymbols3* g_DebugSymbols;
|
||||
extern IDebugDataSpaces* g_DataSpaces;
|
||||
|
||||
HRESULT FindMimallocBase();
|
||||
HRESULT GetSymbolOffset(const char* symbolName, ULONG64& outOffset);
|
||||
HRESULT ReadMemory(const char* symbolName, void* outBuffer, size_t bufferSize);
|
||||
HRESULT ReadMemory(ULONG64 address, void* outBuffer, size_t bufferSize);
|
||||
HRESULT ReadString(const char* symbolName, std::string& outBuffer);
|
||||
|
||||
#endif // MIMALLOC_WINDBG_UTILS_H
|
Loading…
Add table
Add a link
Reference in a new issue