* Most of the main entry points that can fail with relevant reasons now has a
way of specifying a message to return with it. This message can be displayed
to the user to give more information or context about an error.
When two shared objects are symlinked and if one is loaded,
CheckLoadedLibraries detects the other one as loaded too and run hooks a
second time.
Prevent this as it leads to recursive blocking calls in libEGL.
* GL hooks registration was using an obscene amount of stack because MSVC
doesn't share stack for mutually exclusive locals (all the temporary
FunctionHooks) so an executable that reduces the default thread stack size
enough would fail to start.
* We also explicitly allocate 1MB of stack for injecting our DLL in future to
avoid this issue.
Change hooking to use link time symbol address instead of runtime dlsym
Since OSX12 dlsym(RTLD_NEXT,...) returns the interposed symbol not the real symbol
* We never want to inherit these, and e.g. Qt process launches are hardcoded to
always inherit handles so these need to be excluded so files don't stay open.
* By intercepting D3D12.dll's load of D3D12Core.dll and wrapping the COM
interface it gets back, we can load the D3D12Core.dll that we desired.
* As a default, we load the D3D12Core.dll embedded in the capture. There's also
a config setting to allow the user to override this, though in principle this
shouldn't be needed.
* We only do all this if the SDK version used to capture is higher than that
normally available on the system. So if a new runtime isn't in use, we won't
do any hooking at all.
* We need to ensure we remodify LD_LIBRARY_PATH and LD_PRELOAD before fork/exec
if the application (say bash running a script) has overwritten them. We also
don't want these to be accidentally inherited into children if we're not
hooking children - the same for the vulkan env var, which can't be unset
immediately on process injection like the others because it needs to hang
around indefinitely.
* We use ptrace to detect child processes reliably, but that makes us look like
a debugger to the child. * There isn't a reliable and simple way to pass down
a PID to ignore (environment variables are the only simple option I can see,
and they can't be reliably inherited, ptrace to poke data would require lots
of work to figure out _where_ to poke that data).
* So instead we use a semi-heuristic - if the debugger PID is found but it
contains executable pages mapped from librenderdoc.so assume we're still being
ptrace setup'd, and check again next time we want to know if a debugger is
connected.
qrenderdoc/Code/CaptureContext.cpp
- Adds GGP windowing system
renderdoc/driver/ihv/amd/amd_counters.cpp
- Enables AMD counters
renderdoc/driver/vulkan/vk_serialise.cpp
- Handling VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP in pNext
for vkQueuePresentKHR
renderdoc/os/posix/ggp/ggp_callstack.cpp
- Check that the file was opened
popen's access mode was accidentally changed from string to enum used in
FileIO::open() wrappers. This is a posix function and should keep using
the string.
* This prevents unnecessary conversions back and forth between rdcstr and const
char * when going through interfaces. In the OS specific layer this is rarely
an issue because most of the implementations don't convert to rdcstr, but it
is convenient to be able to pass in an rdcstr directly. The few cases where
there's an unecessary construction of an rdcstr is acceptable.
* A couple of places in the public API need to return a string from a global
function, so can't return an rdcstr due to C ABI, so they still return a const
char *.
* Similarly const char * is kept for logging, to avoid a dependency on rdcstr
and because that's one place where unnecessary conversions/constructions may
be impactful.