Juliean said:
On the contrary, I did find some API-functions for supplying symbols to the debugger ad runtime, via SymLoadModuleExW/SymAddSymbolW in DbgHelp.h:
const auto process = GetCurrentProcess();
static bool hasInitialized = false;
if (!hasInitialized)
{
if (!SymInitialize(process, nullptr, false))
Log::OutErrorFmt("Failed to call SymInitialize.");
hasInitialized = true;
}
//if (!SymLoadModuleExW(process, nullptr, L"Test.dll", nullptr, (DWORD64)(pMemory + 8), DWORD(codeSize), nullptr, SLMFLAG_VIRTUAL))
// Log::OutErrorFmt("Failed to call SymLoadModuleEx.");
uint32_t index = 0;
for (const auto [target, bytecode, info] : data.vBytecodeMapping)
{
const auto end = [&]() -> uint32_t
{
const auto next = index + 1;
if (data.vBytecodeMapping.IsValidIndex(next)) [[likely]]
return data.vBytecodeMapping.At(next).target - REFERENCE_SIZE;
else
return uint32_t(codeSize);
}();
const auto code = DWORD64(pMemory + target);
const auto size = end - target;
if (!SymLoadModuleExW(process, nullptr, nullptr, nullptr, code, size, nullptr, SLMFLAG_VIRTUAL))
Log::OutErrorFmt("Failed to call SymLoadModuleEx.");
if (!SymAddSymbolW(process, code, L"Test(void)", code, size, 0))
Log::OutErrorFmt("Failed to call SymAddSymbol.");
index++;
}
This seems to work in supplying a name to the function, but its critically lacking the ability to specify the line/source-file mapping which is being enumerated by SymGetLineFromXXX-functions as well as from the debugger itself. But SymAddSymbol seems to be the only way to “add” anything to the virtual module. Am I missing something, or do I really have to create a PE/COFF-formatted executable alongside a full PDB in order for this symbols to work?
(Sorry for the thread necromancy! I haven't found any better sources of info on SymAddSymbolW.)
Were you actually able to see these global symbols when you attach to your jit engine in Visual Studio? I've been fiddling with SymLoadModuleEx and SymAddSymbol for a while and I can't get VS to display anything. Are the virtual symbols added by the jit really supposed to be visible to the debugger? (i.e. in a different process?) It sort of feels like the dbghelp data you create in the child process would be more likely stay inside the child, rather than being shared to the debugger.
I was hoping e.g. that SymLoadModuleEx would cause a new entry in the “Modules” window of VS, but I don't see that happening. And in “Disassembly” view there are no symbol headings that would normally be there for binary that has a pdb.
My silly plan was to abuse the symbols for a very basic form of debug info, by putting a symbol for each line of the source code where the symbol name is the full line of source code. It wouldn't be the great, but might be sort of useful for a low-level style of debugging.
But… I haven't even been able to get VS to see anything added by SymAddSymbol at all. Any hints or suggestions would be much appreciated! (Writing out a pdb with a stub dll seems possible, but definitely also a pretty large and messy undertaking.)