From 58de3fa8a53b1a2becdd4dcb9a705ca8d3737945 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 18 Oct 2018 19:36:21 +0100 Subject: [PATCH] Walk stackframe to find _renderdoc_internal * When calling functions in modules, the globals are namespaced to the module --- .../Code/pyrenderdoc/function_conversion.h | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/qrenderdoc/Code/pyrenderdoc/function_conversion.h b/qrenderdoc/Code/pyrenderdoc/function_conversion.h index 93274ade3..474ec4ef9 100644 --- a/qrenderdoc/Code/pyrenderdoc/function_conversion.h +++ b/qrenderdoc/Code/pyrenderdoc/function_conversion.h @@ -24,6 +24,8 @@ #pragma once +#include + // this is defined elsewhere for managing the opaque global_handle object extern "C" PyThreadState *GetExecutingThreadState(PyObject *global_handle); extern "C" void HandleException(PyObject *global_handle); @@ -46,7 +48,9 @@ struct ExceptionHandling inline void HandleCallbackFailure(PyObject *global_handle, ExceptionHandling &exHandle) { // if there's no global handle assume we are not running in the usual environment, so there are no - // external-to-python threads + // external-to-python threads. + // Specifically this is when we're imported as a module directly into python with none of our + // harness, so this is running as pure glue code. if(!global_handle) { exHandle.failFlag = true; @@ -205,9 +209,20 @@ funcType ConvertFunc(const char *funcname, PyObject *func, ExceptionHandling &ex // async call PyObject *global_internal_handle = NULL; - PyObject *globals = PyEval_GetGlobals(); - if(globals) - global_internal_handle = PyDict_GetItemString(globals, "_renderdoc_internal"); + // walk the frames until we find one with _renderdoc_internal. If we call a function in another + // module the globals may not have the entry, but the root level is expected to. + { + _frame *frame = PyEval_GetFrame(); + + while(frame) + { + global_internal_handle = PyDict_GetItemString(frame->f_globals, "_renderdoc_internal"); + + if(global_internal_handle) + break; + frame = frame->f_back; + } + } return [global_internal_handle, funcname, func, &exHandle](auto... param) { ScopedFuncCall gil(global_internal_handle);