Debugging on 32bit system

Hello.

Today I tried compiling my system with 32bit on Debug mode.

A preprocessor is triggered and a function StartDebugging will be called.

This setup uses the typedef VkDebugReportCallbackEXT. This typedef is defined as uint64_t.

If I’m calling the linked function created with PFN_vkCreateDebugReportCallbackEXT it fails on 32bit.

Is it just not possible using debugging on 32bit or am I doing something wrong?

Thanks for your advice!

The Vulkan and VK_EXT_debug_report should work just fine on x86.

preprocessor? triggered?

How is that relevant? It is a Vulkan handle. Opaque for most intents and purposes.

Do you have the vkCreateDebugReportCallbackEXT function properly loaded?
Being a EXT extension AFAIK it is not automagically loaded with the official vulkan-1.lib loader.

Exception thrown at 0x0FB70FFF (VkLayer_object_tracker.dll) in Core.exe: 0xC0000005: Access violation reading location 0x00000020.

That’s what it’s telling me. I don’t get it what it is trying to tell me…

That is possibly a Validation Layer bug.
Are you using the latest LunarG SDK?
What is the Vulkan command that crashes, and what are the values of its arguments when it was called?

Also try to temporarily disable the Validation Layers. Does the driver still crash (which dll?)?

Hello KrOoze

I updated my programm to 1.0.61.1 yesterday. I had noticed that problem also with version 1.0.42.0. This problem was the reason updating the vulkan sdk, but nothing changed. The crazy thing is that 64bit runs without problems with the same code.
One thing I noticed is that VkDebugReportCallbackEXT is instantiated to 0 on 32bit while on 64bit it turns into a pointer. That’s why I asked for that comparison.

I’m using VK_LAYER_LUNARG_standard_validation and it crashes always on VkLayer_object_tracker.dll. If I’m disabling the validationlayers the programm works fine also on 32bit.

Well, I am not able to reproduce the error. It works just fine for me in both x64 and x86.

So I need some info to be able to reproduce the crash (unless you want to take it on and propose a fix to the layers yourself).

Relevant code, and/or api_dump, would do.

@krOoze

I found a way to reproduce my error. It is still not solved. (Additional information: I’m linking PFN functions by vkGetInstanceProcAddr …)

If you have some time could you please test it following flags for debugging set?

  1. Set. Three flags set:
    VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT
    result: VK_SUCCESS

  2. Set. One flag
    VK_DEBUG_REPORT_DEBUG_BIT_EXT
    result: -858993460 --> crash

both compiled with x86.

Time to think about that…

Sorry, works for me without issue.

I used this “minimal” example:


#include <iostream>
#include <vector>
#include <string>

#include <vulkan/vulkan.h>

constexpr VkDebugReportFlagsEXT debugAmount = VK_DEBUG_REPORT_DEBUG_BIT_EXT;

PFN_vkCreateInstance pvkCreateInstance;
PFN_vkDestroyInstance pvkDestroyInstance;

PFN_vkCreateDebugReportCallbackEXT pvkCreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT pvkDestroyDebugReportCallbackEXT;

void loadVulkanCmds(){
	const auto fptr = vkGetInstanceProcAddr( nullptr, "vkCreateInstance" );
	if( !fptr ) throw "Failed to load vkCreateInstance!";
	pvkCreateInstance = reinterpret_cast<PFN_vkCreateInstance>( fptr );
}

void loadVulkanCmds( VkInstance instance ){
	{
		const auto fptr = vkGetInstanceProcAddr( instance, "vkDestroyInstance" );
		if( !fptr ) throw "Failed to load vkDestroyInstance!";
		pvkDestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>( fptr );
	}

	{
		const auto fptr = vkGetInstanceProcAddr( instance, "vkCreateDebugReportCallbackEXT" );
		if( !fptr ) throw "Failed to load vkCreateDebugReportCallbackEXT!";
		pvkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( fptr );
	}

	{
		const auto fptr = vkGetInstanceProcAddr( instance, "vkDestroyDebugReportCallbackEXT" );
		if( !fptr ) throw "Failed to load vkDestroyDebugReportCallbackEXT!";
		pvkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( fptr );
	}
}

std::string d_to_string( VkDebugReportFlagsEXT msgFlags ){
	std::string res;
	bool first = true;

	if( msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT ){
		if( !first ) res += " | ";
		res += "ERROR";
		first = false;
	}

	if( msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT ){
		if( !first ) res += " | ";
		res += "WARNING";
		first = false;
	}

	if( msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT ){
		if( !first ) res += " | ";
		res += "PERFORMANCE";
		first = false;
	}

	if( msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT ){
		if( !first ) res += " | ";
		res += "Info";
		first = false;
	}

	if( msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT ){
		if( !first ) res += " | ";
		res += "Debug";
		first = false;
	}

	VkDebugReportFlagsEXT known = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
	if( msgFlags & ~known ){
		if( !first ) res += " | ";
		res += "UNRECOGNIZED_FLAG";
		first = false;
	}

	return res;
}

VKAPI_ATTR VkBool32 VKAPI_CALL genericDebugCallback( VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char* pLayerPrefix, const char* pMessage, void* ){
	std::cout << d_to_string( flags ) << "(" << pLayerPrefix << "): " << pMessage << std::endl;

	return VK_FALSE; // no abort on misbehaving command
}

int main() try {
	loadVulkanCmds();

	VkInstance instance;
	{
		std::vector<const char*> layers = { "VK_LAYER_LUNARG_standard_validation" };
		std::vector<const char*> extensions = { VK_EXT_DEBUG_REPORT_EXTENSION_NAME };
		VkInstanceCreateInfo ici{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
			nullptr, // pNext
			0, // unused flags
			nullptr, // app info
			static_cast<uint32_t>( layers.size() ), layers.data(),
			static_cast<uint32_t>( extensions.size() ), extensions.data()
		};
		VkResult errCode = pvkCreateInstance( &ici, nullptr, &instance );
		if( errCode ) throw "vkCreateInstance failed!";
	}

	loadVulkanCmds( instance );

	VkDebugReportCallbackEXT debugHandle;
	{
		VkDebugReportCallbackCreateInfoEXT drcci{
			VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
			nullptr, // pNext
			::debugAmount,
			::genericDebugCallback,
			nullptr // user data
		};
		VkResult errCode = pvkCreateDebugReportCallbackEXT( instance, &drcci, nullptr, &debugHandle );
		if( errCode ) throw "vkCreateDebugReportCallbackEXT failed!";
	}

	pvkDestroyDebugReportCallbackEXT( instance, debugHandle, nullptr );
	pvkDestroyInstance( instance, nullptr );
}
catch( const char* error ){ std::cout << "ERROR: " << error << std::endl; }
catch( ... ){ std::cout << "ERROR: Unknown error!" << std::endl; }


Does it work for you?
If yes, can you construct similar minimal example that crashes for you?
Or api_dump of your existing code should be sufficient too.

Hello krOoze

I found the problem in my code… Thank you so much…

That was the problem:

My callback function did not look like this: VKAPI_ATTR VkBool32 VKAPI_CALL messageCallback… , it looked like this instead: VkBool32 messageCallback … without VKAPI_ATTR and VKAPI_CALL.

The way I got it into the creation structure was just casting my function like that:
dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback;
but that seems not to be valid for x86.

Now everything is fine. I can’t thank you enough. You saved me much stress and concerns.

Thanks for being here!