Improve vk_debug output a lot by throwing away the useless parts of the message and limit the callstack to the first 5 gzdoom calls

This commit is contained in:
Magnus Norddahl 2022-06-06 01:51:53 +02:00 committed by Christoph Oelckers
parent 0c90a72c66
commit e08965b0b3
3 changed files with 46 additions and 13 deletions

View file

@ -47,7 +47,7 @@
bool I_GetVulkanPlatformExtensions(unsigned int *count, const char **names); bool I_GetVulkanPlatformExtensions(unsigned int *count, const char **names);
bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface); bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface);
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames); FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames, int maxFrames = -1);
// Physical device info // Physical device info
static std::vector<VulkanPhysicalDevice> AvailableDevices; static std::vector<VulkanPhysicalDevice> AvailableDevices;
@ -404,14 +404,25 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess
FString msg = callbackData->pMessage; FString msg = callbackData->pMessage;
// For patent-pending reasons the validation layer apparently can't do this itself.. // Attempt to parse the string because the default formatting is totally unreadable and half of what it writes is totally useless!
for (uint32_t i = 0; i < callbackData->objectCount; i++) auto parts = msg.Split("|");
if (parts.Size() == 3)
{ {
if (callbackData->pObjects[i].pObjectName) msg = parts[2];
auto pos = msg.IndexOf(" The Vulkan spec states:");
if (pos >= 0)
msg = msg.Left(pos);
if (callbackData->objectCount > 0)
{ {
FString hexname; msg += " (";
hexname.Format("0x%" PRIx64, callbackData->pObjects[i].objectHandle); for (uint32_t i = 0; i < callbackData->objectCount; i++)
msg.Substitute(hexname.GetChars(), callbackData->pObjects[i].pObjectName); {
if (i > 0)
msg += ", ";
msg += callbackData->pObjects[i].pObjectName;
}
msg += ")";
} }
} }
@ -454,7 +465,7 @@ VkBool32 VulkanDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess
if (vk_debug_callstack && showcallstack) if (vk_debug_callstack && showcallstack)
{ {
FString callstack = JitCaptureStackTrace(0, true); FString callstack = JitCaptureStackTrace(0, true, 5);
if (!callstack.IsEmpty()) if (!callstack.IsEmpty())
Printf("%s\n", callstack.GetChars()); Printf("%s\n", callstack.GetChars());
} }

View file

@ -5,4 +5,4 @@
JitFuncPtr JitCompile(VMScriptFunction *func); JitFuncPtr JitCompile(VMScriptFunction *func);
void JitDumpLog(FILE *file, VMScriptFunction *func); void JitDumpLog(FILE *file, VMScriptFunction *func);
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames); FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames, int maxFrames = -1);

View file

@ -5,6 +5,7 @@
#ifdef WIN32 #ifdef WIN32
#include <DbgHelp.h> #include <DbgHelp.h>
#include <psapi.h>
#else #else
#include <execinfo.h> #include <execinfo.h>
#include <cxxabi.h> #include <cxxabi.h>
@ -813,8 +814,16 @@ static int CaptureStackTrace(int max_frames, void **out_frames)
class NativeSymbolResolver class NativeSymbolResolver
{ {
public: public:
NativeSymbolResolver() { SymInitialize(GetCurrentProcess(), nullptr, TRUE); } NativeSymbolResolver()
~NativeSymbolResolver() { SymCleanup(GetCurrentProcess()); } {
SymInitialize(GetCurrentProcess(), nullptr, TRUE);
GetModuleInformation(GetCurrentProcess(), GetModuleHandle(0), &moduleInfo, sizeof(MODULEINFO));
}
~NativeSymbolResolver()
{
SymCleanup(GetCurrentProcess());
}
FString GetName(void *frame) FString GetName(void *frame)
{ {
@ -830,6 +839,9 @@ public:
BOOL result = SymGetSymFromAddr64(GetCurrentProcess(), (DWORD64)frame, &displacement, symbol64); BOOL result = SymGetSymFromAddr64(GetCurrentProcess(), (DWORD64)frame, &displacement, symbol64);
if (result) if (result)
{ {
if ((DWORD64)frame < (DWORD64)moduleInfo.lpBaseOfDll || (DWORD64)frame >= ((DWORD64)moduleInfo.lpBaseOfDll + moduleInfo.SizeOfImage))
return s; // Ignore anything not from the exe itself
IMAGEHLP_LINE64 line64; IMAGEHLP_LINE64 line64;
DWORD displacement1 = 0; DWORD displacement1 = 0;
memset(&line64, 0, sizeof(IMAGEHLP_LINE64)); memset(&line64, 0, sizeof(IMAGEHLP_LINE64));
@ -847,6 +859,8 @@ public:
return s; return s;
} }
MODULEINFO moduleInfo = {};
}; };
#else #else
class NativeSymbolResolver class NativeSymbolResolver
@ -952,7 +966,7 @@ FString JitGetStackFrameName(NativeSymbolResolver *nativeSymbols, void *pc)
return nativeSymbols ? nativeSymbols->GetName(pc) : FString(); return nativeSymbols ? nativeSymbols->GetName(pc) : FString();
} }
FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames) FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames, int maxFrames)
{ {
void *frames[32]; void *frames[32];
int numframes = CaptureStackTrace(32, frames); int numframes = CaptureStackTrace(32, frames);
@ -961,10 +975,18 @@ FString JitCaptureStackTrace(int framesToSkip, bool includeNativeFrames)
if (includeNativeFrames) if (includeNativeFrames)
nativeSymbols.reset(new NativeSymbolResolver()); nativeSymbols.reset(new NativeSymbolResolver());
int total = 0;
FString s; FString s;
for (int i = framesToSkip + 1; i < numframes; i++) for (int i = framesToSkip + 1; i < numframes; i++)
{ {
s += JitGetStackFrameName(nativeSymbols.get(), frames[i]); FString name = JitGetStackFrameName(nativeSymbols.get(), frames[i]);
if (!name.IsEmpty())
{
s += name;
total++;
if (maxFrames != -1 && maxFrames == total)
break;
}
} }
return s; return s;
} }