diff --git a/docs/envvars.rst b/docs/envvars.rst index 1c3fbfc6b19..850b2d600f5 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -904,6 +904,12 @@ Anvil(ANV) driver environment variables modifying command buffers to implement ``vkCmdExecuteCommands``. As a result of this, it will also disable :ext:`VK_KHR_performance_query`. +.. envvar:: ANV_DEBUG_WAIT_FOR_ATTACH + + If defined, the value is parsed as a regular expression. If the current + process name matches the regex, ANV will wait 30 seconds for a debugger + to attach before starting device creation. + .. envvar:: ANV_PRIMITIVE_REPLICATION_MAX_VIEWS Specifies up to how many view shaders can be lowered to handle diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 12a3b5d728a..237b464501d 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -312,6 +312,7 @@ VkResult anv_CreateDevice( const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { + anv_wait_for_attach(); ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); VkResult result; struct anv_device *device; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index ac6135bebfd..9bab297b5f2 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2390,6 +2390,8 @@ void anv_device_print_fini(struct anv_device *device); void anv_dump_bvh_to_files(struct anv_device *device); +void anv_wait_for_attach(void); + VkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue, const VkDeviceQueueCreateInfo *pCreateInfo, uint32_t index_in_family); diff --git a/src/intel/vulkan/anv_util.c b/src/intel/vulkan/anv_util.c index 1e6063938d1..f4143058d2d 100644 --- a/src/intel/vulkan/anv_util.c +++ b/src/intel/vulkan/anv_util.c @@ -33,6 +33,19 @@ #include "anv_private.h" #include "vk_enum_to_str.h" +#ifdef NO_REGEX +typedef int regex_t; +#define REG_EXTENDED 0 +#define REG_NOSUB 0 +#define REG_NOMATCH 1 +static inline int regcomp(regex_t *r, const char *s, int f) { return 0; } +static inline int regexec(regex_t *r, const char *s, int n, void *p, int f) { return REG_NOMATCH; } +static inline void regfree(regex_t* r) {} +#else +#include +#endif +#include "util/u_process.h" + void __anv_perf_warn(struct anv_device *device, const struct vk_object_base *object, @@ -289,3 +302,31 @@ void anv_dump_bvh_to_files(struct anv_device *device) free(bvh_dump); } } + +DEBUG_GET_ONCE_OPTION(anv_debug_wait_for_attach, "ANV_DEBUG_WAIT_FOR_ATTACH", NULL); + +void anv_wait_for_attach() { + const char *attach_regex = + debug_get_option_anv_debug_wait_for_attach(); + if (unlikely(attach_regex != NULL)) { + bool wait_for_attach = false; + const char *exec_name = util_get_process_name(); + regex_t re; + int compile_res = regcomp(&re, attach_regex, REG_EXTENDED|REG_NOSUB); + if (compile_res != 0) { + char compile_err[256]; + regerror(compile_res, &re, compile_err, 256); + fprintf(stderr, "ANV_DEBUG_WAIT_FOR_ATTACH regex compile fail: %s\n", + compile_err); + } else { + wait_for_attach = (regexec(&re, exec_name, 0, NULL, 0) == 0); + regfree(&re); + } + + if (wait_for_attach) { + fprintf(stderr, "Sleeping 30 seconds for debugger attach...\n"); + fprintf(stderr, "PID for debugger: %d\n", getpid()); + sleep(30); + } + } +}