Skip to content

Instantly share code, notes, and snippets.

@SoapyMan
Created July 22, 2026 08:16
Show Gist options
  • Select an option

  • Save SoapyMan/e00d5505c3804420f8e81c70a4a7ec76 to your computer and use it in GitHub Desktop.

Select an option

Save SoapyMan/e00d5505c3804420f8e81c70a4a7ec76 to your computer and use it in GitHub Desktop.
List dynamic initializers with MSVC CRT
// Dynamic initializer names
// Based on https://x.com/molecularmusing/status/2079654839005393235
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
PRAGMA_OPTIMIZE_OFF
typedef void(__cdecl* _PVFV)(void);
extern "C" _PVFV __xc_a[];
extern "C" _PVFV __xc_z[];
struct InspectGlobalInitializers
{
InspectGlobalInitializers()
{
SymInitialize(GetCurrentProcess(), NULL, TRUE);
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
const _PVFV* begin = __xc_a;
const _PVFV* end = __xc_z;
int cnt = 0;
for (const _PVFV* ptr = begin; ptr < end; ++ptr)
{
const _PVFV initializer = *ptr;
if (initializer)
++cnt;
}
names.reserve(cnt);
for (const _PVFV* ptr = begin; ptr < end; ++ptr)
{
const _PVFV initializer = *ptr;
if (initializer)
ResolveName((DWORD64)initializer);
}
}
void ResolveName(DWORD64 addr)
{
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
DWORD64 displacement = 0;
if (SymFromAddr(GetCurrentProcess(), addr, &displacement, pSymbol))
names.append(EqString::Format("%s", &pSymbol->Name));
else
names.append(EqString::Format("0x%llX: <no symbol>", addr));
}
Array<EqString> names{ PPSourceLine::Empty() };
};
#pragma warning(push)
#pragma warning(disable: 4074)
#pragma init_seg(compiler)
static InspectGlobalInitializers globalsInspector;
#pragma warning(pop)
PRAGMA_OPTIMIZE_ON
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment