dotfiles

personal dotfiles
git clone anongit@rnpnr.xyz:dotfiles.git
Log | Files | Refs | Feed | Submodules

Commit: 524fa977e01a4f1f95c263f85d0c1bf88055f174
Parent: a4119f7da4eddd0bea9435214d1aa7c2f7287e0c
Author: Randy Palamar
Date:   Tue,  4 Mar 2025 15:32:24 -0700

portage: update renderdoc patches for v1.37

Diffstat:
A.config/sys/etc/portage/patches/media-gfx/renderdoc/0001-linux-fix-build-against-musl.patch | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.config/sys/etc/portage/patches/media-gfx/renderdoc/0002-Rework-injection-and-synchronisaion-on-linux.patch | 606+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
D.config/sys/etc/portage/patches/media-gfx/renderdoc/musl-fix.patch | 52----------------------------------------------------
D.config/sys/etc/portage/patches/media-gfx/renderdoc/musl_program_injection.patch | 581-------------------------------------------------------------------------------
D.config/sys/etc/portage/patches/media-gfx/renderdoc/no-execinfo.patch | 21---------------------
5 files changed, 694 insertions(+), 654 deletions(-)

diff --git a/.config/sys/etc/portage/patches/media-gfx/renderdoc/0001-linux-fix-build-against-musl.patch b/.config/sys/etc/portage/patches/media-gfx/renderdoc/0001-linux-fix-build-against-musl.patch @@ -0,0 +1,88 @@ +From fa6fabb9c078dca6b67c7a4168f0e536812da225 Mon Sep 17 00:00:00 2001 +From: Randy Palamar <randy@rnpnr.xyz> +Date: Tue, 4 Mar 2025 15:12:11 -0700 +Subject: [PATCH 1/2] linux: fix build against musl + +--- + renderdoc/3rdparty/plthook/plthook_elf.c | 6 +++++- + renderdoc/os/os_specific.h | 1 + + renderdoc/os/posix/linux/linux_callstack.cpp | 3 +-- + renderdoc/os/posix/linux/linux_hook.cpp | 4 ++++ + 4 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/renderdoc/3rdparty/plthook/plthook_elf.c b/renderdoc/3rdparty/plthook/plthook_elf.c +index 6fc2ac6e3..3926ef6d0 100644 +--- a/renderdoc/3rdparty/plthook/plthook_elf.c ++++ b/renderdoc/3rdparty/plthook/plthook_elf.c +@@ -236,7 +236,11 @@ int plthook_open_by_address(plthook_t **plthook_out, void *address) + struct link_map *lmap = NULL; + + *plthook_out = NULL; ++#ifdef __GLIBC__ + if (dladdr1(address, &info, (void**)&lmap, RTLD_DL_LINKMAP) == 0) { ++#else ++ if (dladdr(address, &info) == 0) { ++#endif + set_errmsg("dladdr error"); + return PLTHOOK_FILE_NOT_FOUND; + } +@@ -246,7 +250,7 @@ int plthook_open_by_address(plthook_t **plthook_out, void *address) + + static int plthook_open_executable(plthook_t **plthook_out) + { +-#if defined __linux__ ++#if defined __linux__ && defined __GLIBC__ + return plthook_open_real(plthook_out, _r_debug.r_map); + #elif defined __sun + const char *auxv_file = "/proc/self/auxv"; +diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h +index a11dec357..882c30e5a 100644 +--- a/renderdoc/os/os_specific.h ++++ b/renderdoc/os/os_specific.h +@@ -31,6 +31,7 @@ + + #pragma once + ++#include <time.h> + #include <stdarg.h> + #include <stddef.h> + #include <stdint.h> +diff --git a/renderdoc/os/posix/linux/linux_callstack.cpp b/renderdoc/os/posix/linux/linux_callstack.cpp +index e6151a7e5..a70648684 100644 +--- a/renderdoc/os/posix/linux/linux_callstack.cpp ++++ b/renderdoc/os/posix/linux/linux_callstack.cpp +@@ -27,7 +27,6 @@ + #define _GNU_SOURCE + #endif + +-#include <execinfo.h> + #include <link.h> + #include <stdio.h> + #include <string.h> +@@ -66,7 +65,7 @@ private: + { + void *addrs_ptr[ARRAY_COUNT(addrs)]; + +- int ret = backtrace(addrs_ptr, ARRAY_COUNT(addrs)); ++ int ret = 0; + + numLevels = 0; + if(ret > 0) +diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp +index 6e6a781a8..56ec173c1 100644 +--- a/renderdoc/os/posix/linux/linux_hook.cpp ++++ b/renderdoc/os/posix/linux/linux_hook.cpp +@@ -36,6 +36,10 @@ + #include "plthook/plthook.h" + #include "strings/string_utils.h" + ++#ifndef __GLIBC__ ++#define RTLD_DEEPBIND 0 ++#endif ++ + Threading::CriticalSection libLock; + + RDOC_EXTERN_CONFIG(bool, Linux_Debug_PtraceLogging); +-- +2.45.2 + diff --git a/.config/sys/etc/portage/patches/media-gfx/renderdoc/0002-Rework-injection-and-synchronisaion-on-linux.patch b/.config/sys/etc/portage/patches/media-gfx/renderdoc/0002-Rework-injection-and-synchronisaion-on-linux.patch @@ -0,0 +1,606 @@ +From 18cd5579dc447a2b99c509403aed0b004b04db52 Mon Sep 17 00:00:00 2001 +From: Jules Maselbas <jmaselbas@zdiv.net> +Date: Mon, 22 Jan 2024 17:55:21 +0100 +Subject: [PATCH 2/2] Rework injection and synchronisaion on linux + +--- + renderdoc/os/posix/linux/linux_hook.cpp | 3 - + renderdoc/os/posix/linux/linux_network.cpp | 6 +- + renderdoc/os/posix/linux/linux_process.cpp | 505 +-------------------- + renderdoc/os/posix/posix_process.cpp | 5 +- + 4 files changed, 13 insertions(+), 506 deletions(-) + +diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp +index 56ec173c1..99f16932e 100644 +--- a/renderdoc/os/posix/linux/linux_hook.cpp ++++ b/renderdoc/os/posix/linux/linux_hook.cpp +@@ -103,7 +103,6 @@ void PreForkConfigureHooks(); + void GetUnhookedEnvp(char *const *envp, rdcstr &envpStr, rdcarray<char *> &modifiedEnv); + void GetHookedEnvp(char *const *envp, rdcstr &envpStr, rdcarray<char *> &modifiedEnv); + void ResetHookingEnvVars(); +-void StopAtMainInChild(); + bool StopChildAtMain(pid_t childPid, bool *exitWithNoExec); + void ResumeProcess(pid_t childPid, uint32_t delay = 0); + int direct_setenv(const char *name, const char *value, int overwrite); +@@ -317,8 +316,6 @@ __attribute__((visibility("default"))) pid_t fork() + { + if(Linux_Debug_PtraceLogging()) + RDCLOG("hooked fork() in child %d", getpid()); +- +- StopAtMainInChild(); + } + else if(ret > 0) + { +diff --git a/renderdoc/os/posix/linux/linux_network.cpp b/renderdoc/os/posix/linux/linux_network.cpp +index 8be1a19dd..382ce6bfb 100644 +--- a/renderdoc/os/posix/linux/linux_network.cpp ++++ b/renderdoc/os/posix/linux/linux_network.cpp +@@ -25,6 +25,8 @@ + #include "os/os_specific.h" + #include "os/posix/posix_network.h" + ++void StopAtMainInChild(); ++ + namespace Network + { + void SocketPostSend() +@@ -39,6 +41,8 @@ uint32_t Socket::GetRemoteIP() const + + Socket *CreateServerSocket(const rdcstr &bindaddr, uint16_t port, int queuesize) + { +- return CreateTCPServerSocket(bindaddr, port, queuesize); ++ Socket *s = CreateTCPServerSocket(bindaddr, port, queuesize); ++ StopAtMainInChild(); ++ return s; + } + }; +diff --git a/renderdoc/os/posix/linux/linux_process.cpp b/renderdoc/os/posix/linux/linux_process.cpp +index aa9c7393c..db0fe9116 100644 +--- a/renderdoc/os/posix/linux/linux_process.cpp ++++ b/renderdoc/os/posix/linux/linux_process.cpp +@@ -164,512 +164,21 @@ int GetIdentPort(pid_t childPid) + return ret; + } + +-static bool ptrace_scope_ok() +-{ +- if(!Linux_PtraceChildProcesses()) +- return false; +- +- rdcstr contents; +- FileIO::ReadAll("/proc/sys/kernel/yama/ptrace_scope", contents); +- contents.trim(); +- if(!contents.empty()) +- { +- int ptrace_scope = atoi(contents.c_str()); +- if(ptrace_scope > 1) +- { +- if(RenderDoc::Inst().IsReplayApp()) +- { +- static bool warned = false; +- if(!warned) +- { +- warned = true; +- RDCWARN( +- "ptrace_scope value %d means ptrace can't be used to pause child processes while " +- "attaching.", +- ptrace_scope); +- } +- } +- return false; +- } +- } +- +- return true; +-} +- +-static uint64_t get_nanotime() +-{ +- timespec ts; +- clock_gettime(CLOCK_MONOTONIC, &ts); +- uint64_t ret = uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff); +- return ret; +-} +- +-#if defined(__arm__) +- +-// for some reason arm doesn't have the same struct name. Sigh :( +-#define user_regs_struct user_regs +- +-#define INST_PTR_REG ARM_pc +- +-#define BREAK_INST 0xe7f001f0ULL +-#define BREAK_INST_BYTES_SIZE 4 +-// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify +-// the instruction pointer at all. +-#define BREAK_INST_INST_PTR_ADJUST 0 +- +-#elif defined(__aarch64__) +- +-#define INST_PTR_REG pc +- +-#define BREAK_INST 0xd4200000ULL +-#define BREAK_INST_BYTES_SIZE 4 +-// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify +-// the instruction pointer at all. +-#define BREAK_INST_INST_PTR_ADJUST 0 +- +-#elif defined(__riscv) +- +-#define INST_PTR_REG pc +- +-// ebreak +-#define BREAK_INST 0x00100073ULL +-#define BREAK_INST_BYTES_SIZE 4 +-#define BREAK_INST_INST_PTR_ADJUST 4 +- +-#else +- +-#define BREAK_INST 0xccULL +-#define BREAK_INST_BYTES_SIZE 1 +-// step back over the instruction +-#define BREAK_INST_INST_PTR_ADJUST 1 +- +-#if ENABLED(RDOC_X64) +-#define INST_PTR_REG rip +-#else +-#define INST_PTR_REG eip +-#endif +- +-#endif +- +-static uint64_t get_child_ip(pid_t childPid) +-{ +- user_regs_struct regs = {}; +- +- iovec regs_iovec = {&regs, sizeof(regs)}; +- long ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); +- if(ptraceRet == 0) +- return uint64_t(regs.INST_PTR_REG); +- +- return 0; +-} +- +-static bool wait_traced_child(pid_t childPid, uint32_t timeoutMS, int &status) +-{ +- // spin waiting for the traced child, with a 100ms timeout +- status = 0; +- uint64_t start_nano = get_nanotime(); +- uint64_t end_nano = 0; +- int ret = 0; +- +- const uint64_t timeoutNanoseconds = uint64_t(timeoutMS) * 1000 * 1000; +- +- while((ret = waitpid(childPid, &status, WNOHANG)) == 0) +- { +- status = 0; +- +- // if we're in a capturing process then the process itself might have done waitpid(-1) and +- // swallowed the wait for our child. So as an alternative we check to see if we can query the +- // instruction pointer, which is only possible if the child is stopped. +- uint64_t ip = get_child_ip(childPid); +- if(ip != 0) +- { +- // do waitpid again in case we raced and the child stopped in between the call to waitpid and +- // get_child_ip. +- ret = waitpid(childPid, &status, WNOHANG); +- +- // if it still didn't succeed, set status to 0 so we know we're earlying out and don't check +- // the status codes. +- if(ret == 0) +- status = 0; +- return true; +- } +- +- usleep(10); +- +- // check the timeout +- end_nano = get_nanotime(); +- if(end_nano - start_nano > timeoutNanoseconds) +- break; +- } +- +- return WIFSTOPPED(status); +-} +- + bool StopChildAtMain(pid_t childPid, bool *exitWithNoExec) + { +- // don't do this unless the ptrace scope is OK. +- if(!ptrace_scope_ok()) +- return false; ++ int stat; ++ pid_t pid = waitpid(childPid, &stat, WUNTRACED); ++ return pid == childPid && WIFSTOPPED(stat); ++} + +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Stopping child PID %u at main", childPid); +- +- int childStatus = 0; +- +- // we have a low timeout for this stop since it should happen almost immediately (right after the +- // fork). If it didn't then we want to fail relatively fast. +- if(!wait_traced_child(childPid, 100, childStatus)) +- { +- RDCERR("Didn't get initial stop from child PID %u", childPid); +- return false; +- } +- +- if(childStatus > 0 && WSTOPSIG(childStatus) != SIGSTOP) +- { +- RDCERR("Initial signal from child PID %u was %x, expected %x", childPid, WSTOPSIG(childStatus), +- SIGSTOP); +- return false; +- } +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Child PID %u is stopped in StopAtMainInChild()", childPid); +- +- int64_t ptraceRet = 0; +- +- // continue until exec +- ptraceRet = ptrace(PTRACE_SETOPTIONS, childPid, NULL, PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Child PID %u configured to trace exec(). Continuing child", childPid); +- +- // continue +- ptraceRet = ptrace(PTRACE_CONT, childPid, NULL, NULL); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- // we're not under control of when the application calls exec() after fork() in the case of child +- // processes, so be a little more generous with the timeout +- if(!wait_traced_child(childPid, 250, childStatus)) +- { +- RDCERR("Didn't get to execve in child PID %u", childPid); +- return false; +- } +- +- int statusResult = childStatus >> 8; +- +- if(childStatus > 0 && +- (statusResult == SIGCHLD || statusResult == (SIGTRAP | (PTRACE_EVENT_EXIT << 8)))) +- { +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Child PID %u exited while waiting for exec() 0x%x", childPid, childStatus); +- if(exitWithNoExec) +- *exitWithNoExec = true; +- +- if(statusResult == SIGCHLD) +- ptrace(PTRACE_DETACH, childPid, NULL, SIGCHLD); +- else +- ptrace(PTRACE_DETACH, childPid, NULL, NULL); +- return false; +- } +- +- if(childStatus > 0 && statusResult != (SIGTRAP | (PTRACE_EVENT_EXEC << 8))) +- { +- RDCERR("Exec wait event from child PID %u was status 0x%x, expected 0x%x", childPid, +- statusResult, (SIGTRAP | (PTRACE_EVENT_EXEC << 8))); +- +- return false; +- } +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Child PID %u is stopped at execve() 0x%x", childPid, childStatus); +- +- rdcstr exepath; +- long baseVirtualPointer = 0; +- uint32_t sectionOffset = 0; +- +- rdcstr mapsName = StringFormat::Fmt("/proc/%u/maps", childPid); +- +- FILE *maps = FileIO::fopen(mapsName, FileIO::ReadText); +- +- if(!maps) +- { +- RDCERR("Couldn't open %s", mapsName.c_str()); +- return false; +- } +- +- while(!feof(maps)) +- { +- char line[512] = {0}; +- if(fgets(line, 511, maps)) +- { +- char *sp = strchr(line, ' '); +- if(sp == NULL) +- continue; +- +- sp++; +- +- if(!strncmp(sp, "r-xp", 4)) +- { +- RDCCOMPILE_ASSERT(sizeof(long) == sizeof(void *), "Expected long to be pointer sized"); +- int pathOffset = 0; +- int num = sscanf(line, "%lx-%*x r-xp %x %*x:%*x %*u %n", &baseVirtualPointer, +- &sectionOffset, &pathOffset); +- +- if(num != 2 || pathOffset == 0) +- { +- RDCERR("Couldn't parse first executable mapping '%s'", rdcstr(line).trimmed().c_str()); +- return false; +- } +- +- exepath = line + pathOffset; +- exepath.trim(); +- break; +- } +- } +- } +- +- if(baseVirtualPointer == 0) +- { +- RDCERR("Couldn't find executable mapping in maps file"); +- return false; +- } +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Child PID %u has exepath %s basePointer 0x%llx and sectionOffset 0x%x", childPid, +- exepath.c_str(), (uint64_t)baseVirtualPointer, (uint32_t)sectionOffset); +- +- FileIO::fclose(maps); +- +- FILE *elf = FileIO::fopen(exepath, FileIO::ReadText); +- +- if(!elf) +- { +- RDCERR("Couldn't open %s to parse ELF header", exepath.c_str()); +- return false; +- } +- +- Elf64_Ehdr elf_header; +- size_t read = FileIO::fread(&elf_header, sizeof(elf_header), 1, elf); +- +- if(read != 1) +- { +- FileIO::fclose(elf); +- RDCERR("Couldn't read ELF header from %s", exepath.c_str()); +- return false; +- } +- +- size_t entryVirtual = (size_t)elf_header.e_entry; +- // if the section doesn't shift between file offset and virtual address this will be the same +- size_t entryFileOffset = entryVirtual; +- +- if(elf_header.e_shoff) +- { +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("exepath %s contains sections, rebasing to correct section", exepath.c_str()); +- +- FileIO::fseek64(elf, elf_header.e_shoff, SEEK_SET); +- +- RDCASSERTEQUAL(elf_header.e_shentsize, sizeof(Elf64_Shdr)); +- +- for(Elf64_Half s = 0; s < elf_header.e_shnum; s++) +- { +- Elf64_Shdr section_header; +- read = FileIO::fread(&section_header, sizeof(section_header), 1, elf); +- +- if(read != 1) +- { +- FileIO::fclose(elf); +- RDCERR("Couldn't read section header from %s", exepath.c_str()); +- return false; +- } +- +- if(section_header.sh_addr <= entryVirtual && +- entryVirtual < section_header.sh_addr + section_header.sh_size) +- { +- if(Linux_Debug_PtraceLogging()) +- RDCLOG( +- "Found section in %s from 0x%llx - 0x%llx at offset 0x%llx containing entry 0x%llx.", +- exepath.c_str(), (uint64_t)section_header.sh_addr, +- uint64_t(section_header.sh_addr + section_header.sh_size), +- (uint64_t)section_header.sh_offset, (uint64_t)entryVirtual); +- +- entryFileOffset = +- (entryVirtual - (size_t)section_header.sh_addr) + (size_t)section_header.sh_offset; +- +- break; +- } +- } +- } +- +- FileIO::fclose(elf); +- +- void *entry = (void *)(baseVirtualPointer + entryFileOffset - sectionOffset); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("child process %u executable %s has entry %p at 0x%llx + (0x%llx - 0x%x)", childPid, +- exepath.c_str(), entry, (uint64_t)baseVirtualPointer, (uint64_t)entryFileOffset, +- (uint32_t)sectionOffset); +- +- // this reads a 'word' and returns as long, upcast (if needed) to uint64_t +- uint64_t origEntryWord = (uint64_t)ptrace(PTRACE_PEEKTEXT, childPid, entry, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Read word %llx from %p in child process %u running executable %s", +- (uint64_t)origEntryWord, entry, childPid, exepath.c_str()); +- +- uint64_t breakpointWord = +- (origEntryWord & (0xffffffffffffffffULL << (BREAK_INST_BYTES_SIZE * 8))) | BREAK_INST; +- // downcast back to long, if that means truncating +- ptraceRet = ptrace(PTRACE_POKETEXT, childPid, entry, (long)breakpointWord); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Changed word to %llx and re-poked in process %u. Continuing child", +- (uint64_t)breakpointWord, childPid); +- +- // continue +- ptraceRet = ptrace(PTRACE_CONT, childPid, NULL, NULL); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- // it could take a long time to hit main so we have a large timeout here +- if(!wait_traced_child(childPid, 2000, childStatus)) +- { +- RDCERR("Didn't hit breakpoint in PID %u (%x)", childPid, childStatus); +- return false; +- } +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Process %u hit entry point", childPid); +- +- // we're now at main! now just need to clean up after ourselves +- +- user_regs_struct regs = {}; +- +- iovec regs_iovec = {&regs, sizeof(regs)}; +- ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Process %u instruction pointer is at %llx, for entry point %p", childPid, +- (uint64_t)(regs.INST_PTR_REG), entry); +- +- // step back past the byte(s) we inserted the breakpoint on +- regs.INST_PTR_REG -= BREAK_INST_INST_PTR_ADJUST; +- ptraceRet = ptrace(PTRACE_SETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- // restore the function +- ptraceRet = ptrace(PTRACE_POKETEXT, childPid, entry, origEntryWord); +- RDCASSERTEQUAL(ptraceRet, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Process %u instruction pointer adjusted and breakpoint removed.", childPid); +- +- // we'll resume after reading the ident port in the calling function +- return true; ++void ResumeProcess(pid_t childPid, uint32_t delay = 0) ++{ ++ kill(childPid, SIGCONT); + } + + void StopAtMainInChild() + { +- // don't do this unless the ptrace scope is OK. +- if(!ptrace_scope_ok()) +- return; +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Stopping in main at child for ptracing"); +- +- // allow parent tracing, and immediately stop so the parent process can attach +- ptrace(PTRACE_TRACEME, 0, 0, 0); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Done PTRACE_TRACEME, raising SIGSTOP"); +- + raise(SIGSTOP); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Resumed after SIGSTOP"); +-} +- +-void ResumeProcess(pid_t childPid, uint32_t delaySeconds) +-{ +- if(!ptrace_scope_ok()) +- return; +- +- if(childPid != 0) +- { +- // if we have a delay, see if the process is paused. If so then detach it but keep it stopped +- // and wait to see if someone attaches +- if(delaySeconds > 0) +- { +- uint64_t ip = get_child_ip(childPid); +- +- if(ip != 0) +- { +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Detaching %u with SIGSTOP to allow a debugger to attach, waiting %u seconds", +- childPid, delaySeconds); +- +- // detach but stop, to allow a debugger to attach +- ptrace(PTRACE_DETACH, childPid, NULL, SIGSTOP); +- +- rdcstr filename = StringFormat::Fmt("/proc/%u/status", childPid); +- +- uint64_t start_nano = get_nanotime(); +- uint64_t end_nano = 0; +- +- const uint64_t timeoutNanoseconds = uint64_t(delaySeconds) * 1000 * 1000 * 1000; +- +- bool connected = false; +- +- // watch for a tracer to attach +- do +- { +- usleep(10); +- +- rdcstr status; +- FileIO::ReadAll(filename, status); +- +- int32_t offs = status.find("TracerPid:"); +- +- if(offs < 0) +- break; +- +- status.erase(0, offs + sizeof("TracerPid:")); +- status.trim(); +- +- end_nano = get_nanotime(); +- +- if(status[0] != '0') +- { +- RDCLOG("Debugger PID %u attached after %f seconds", atoi(status.c_str()), +- double(end_nano - start_nano) / 1000000000.0); +- connected = true; +- break; +- } +- } while(end_nano - start_nano < timeoutNanoseconds); +- +- if(!connected) +- { +- RDCLOG("Timed out waiting for debugger, resuming"); +- kill(childPid, SIGCONT); +- } +- return; +- } +- else +- { +- RDCERR("Can't delay for debugger without ptrace, check ptrace_scope value"); +- } +- } +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Detaching immediately from %u", childPid); +- +- // try to detach and resume the process, ignoring any errors if we weren't tracing +- long ret = ptrace(PTRACE_DETACH, childPid, NULL, NULL); +- +- if(Linux_Debug_PtraceLogging()) +- RDCLOG("Detached pid %u (%ld)", childPid, ret); +- } + } + + // because OSUtility::DebuggerPresent is called often we want it to be +diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp +index 1adefb0d8..488a171c8 100644 +--- a/renderdoc/os/posix/posix_process.cpp ++++ b/renderdoc/os/posix/posix_process.cpp +@@ -447,7 +447,7 @@ static void CleanupStringArray(char **arr) + + while(*arr) + { +- delete[] * arr; ++ delete[] *arr; + arr++; + } + +@@ -608,9 +608,6 @@ static pid_t RunProcess(rdcstr appName, rdcstr workDir, const rdcstr &cmdLine, c + childPid = fork(); + if(childPid == 0) + { +- if(pauseAtMain) +- StopAtMainInChild(); +- + FileIO::ReleaseFDAfterFork(); + if(stdoutPipe) + { +-- +2.45.2 + diff --git a/.config/sys/etc/portage/patches/media-gfx/renderdoc/musl-fix.patch b/.config/sys/etc/portage/patches/media-gfx/renderdoc/musl-fix.patch @@ -1,52 +0,0 @@ -diff --git a/renderdoc/3rdparty/plthook/plthook_elf.c b/renderdoc/3rdparty/plthook/plthook_elf.c -index 612f689d6..907e7f63e 100644 ---- a/renderdoc/3rdparty/plthook/plthook_elf.c -+++ b/renderdoc/3rdparty/plthook/plthook_elf.c -@@ -233,7 +233,11 @@ int plthook_open_by_address(plthook_t **plthook_out, void *address) - struct link_map *lmap = NULL; - - *plthook_out = NULL; -+#ifdef __GLIBC__ - if (dladdr1(address, &info, (void**)&lmap, RTLD_DL_LINKMAP) == 0) { -+#else -+ if (dladdr(address, &info) == 0) { -+#endif - set_errmsg("dladdr error"); - return PLTHOOK_FILE_NOT_FOUND; - } -@@ -243,7 +247,7 @@ int plthook_open_by_address(plthook_t **plthook_out, void *address) - - static int plthook_open_executable(plthook_t **plthook_out) - { --#if defined __linux__ -+#if defined __linux__ && defined __GLIBC__ - return plthook_open_real(plthook_out, _r_debug.r_map); - #elif defined __sun - const char *auxv_file = "/proc/self/auxv"; -diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h -index cc9a6b09e..844597450 100644 ---- a/renderdoc/os/os_specific.h -+++ b/renderdoc/os/os_specific.h -@@ -31,6 +31,7 @@ - - #pragma once - -+#include <time.h> - #include <stdarg.h> - #include <stddef.h> - #include <stdint.h> -diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp -index 4989e2865..0acb3ac0b 100644 ---- a/renderdoc/os/posix/linux/linux_hook.cpp -+++ b/renderdoc/os/posix/linux/linux_hook.cpp -@@ -36,6 +36,10 @@ - #include "plthook/plthook.h" - #include "strings/string_utils.h" - -+#ifndef __GLIBC__ -+#define RTLD_DEEPBIND 0 -+#endif -+ - Threading::CriticalSection libLock; - - RDOC_EXTERN_CONFIG(bool, Linux_Debug_PtraceLogging); diff --git a/.config/sys/etc/portage/patches/media-gfx/renderdoc/musl_program_injection.patch b/.config/sys/etc/portage/patches/media-gfx/renderdoc/musl_program_injection.patch @@ -1,581 +0,0 @@ -From 41ac532478fe95013ec2a2570aa49a7e7c787920 Mon Sep 17 00:00:00 2001 -From: Jules Maselbas <jmaselbas@zdiv.net> -Date: Mon, 22 Jan 2024 17:55:21 +0100 -Subject: [PATCH 2/2] Rework injection and synchronisaion on linux - -for the record, modification to "fix" https://github.com/baldurk/renderdoc/issues/3228 ---- - renderdoc/os/posix/linux/linux_hook.cpp | 2 - - renderdoc/os/posix/linux/linux_network.cpp | 5 +- - renderdoc/os/posix/linux/linux_process.cpp | 500 +-------------------- - renderdoc/os/posix/posix_process.cpp | 3 - - 4 files changed, 12 insertions(+), 498 deletions(-) - -diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp -index 7138904d87..1a8ba65cb9 100644 ---- a/renderdoc/os/posix/linux/linux_hook.cpp -+++ b/renderdoc/os/posix/linux/linux_hook.cpp -@@ -313,8 +313,6 @@ __attribute__((visibility("default"))) pid_t fork() - { - if(Linux_Debug_PtraceLogging()) - RDCLOG("hooked fork() in child %d", getpid()); -- -- StopAtMainInChild(); - } - else if(ret > 0) - { -diff --git a/renderdoc/os/posix/linux/linux_network.cpp b/renderdoc/os/posix/linux/linux_network.cpp -index 4b67d3d18e..ba333db13f 100644 ---- a/renderdoc/os/posix/linux/linux_network.cpp -+++ b/renderdoc/os/posix/linux/linux_network.cpp -@@ -24,6 +24,7 @@ - - #include "os/os_specific.h" - #include "os/posix/posix_network.h" -+void StopAtMainInChild(); - - namespace Network - { -@@ -39,6 +40,8 @@ uint32_t Socket::GetRemoteIP() const - - Socket *CreateServerSocket(const rdcstr &bindaddr, uint16_t port, int queuesize) - { -- return CreateTCPServerSocket(bindaddr, port, queuesize); -+ Socket *s = CreateTCPServerSocket(bindaddr, port, queuesize); -+ StopAtMainInChild(); -+ return s; - } - }; -diff --git a/renderdoc/os/posix/linux/linux_process.cpp b/renderdoc/os/posix/linux/linux_process.cpp -index 4130e9e8dc..0a5831b3a0 100644 ---- a/renderdoc/os/posix/linux/linux_process.cpp -+++ b/renderdoc/os/posix/linux/linux_process.cpp -@@ -164,506 +164,22 @@ int GetIdentPort(pid_t childPid) - return ret; - } - --static bool ptrace_scope_ok() --{ -- if(!Linux_PtraceChildProcesses()) -- return false; -- -- rdcstr contents; -- FileIO::ReadAll("/proc/sys/kernel/yama/ptrace_scope", contents); -- contents.trim(); -- if(!contents.empty()) -- { -- int ptrace_scope = atoi(contents.c_str()); -- if(ptrace_scope > 1) -- { -- if(RenderDoc::Inst().IsReplayApp()) -- { -- static bool warned = false; -- if(!warned) -- { -- warned = true; -- RDCWARN( -- "ptrace_scope value %d means ptrace can't be used to pause child processes while " -- "attaching.", -- ptrace_scope); -- } -- } -- return false; -- } -- } -- -- return true; --} -- --static uint64_t get_nanotime() --{ -- timespec ts; -- clock_gettime(CLOCK_MONOTONIC, &ts); -- uint64_t ret = uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff); -- return ret; --} -- --#if defined(__arm__) -- --// for some reason arm doesn't have the same struct name. Sigh :( --#define user_regs_struct user_regs -- --#define INST_PTR_REG ARM_pc -- --#define BREAK_INST 0xe7f001f0ULL --#define BREAK_INST_BYTES_SIZE 4 --// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify --// the instruction pointer at all. --#define BREAK_INST_INST_PTR_ADJUST 0 -- --#elif defined(__aarch64__) -- --#define INST_PTR_REG pc -- --#define BREAK_INST 0xd4200000ULL --#define BREAK_INST_BYTES_SIZE 4 --// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify --// the instruction pointer at all. --#define BREAK_INST_INST_PTR_ADJUST 0 -- --#elif defined(__riscv) -- --#define INST_PTR_REG pc -- --// ebreak --#define BREAK_INST 0x00100073ULL --#define BREAK_INST_BYTES_SIZE 4 --#define BREAK_INST_INST_PTR_ADJUST 4 -- --#else -- --#define BREAK_INST 0xccULL --#define BREAK_INST_BYTES_SIZE 1 --// step back over the instruction --#define BREAK_INST_INST_PTR_ADJUST 1 -- --#if ENABLED(RDOC_X64) --#define INST_PTR_REG rip --#else --#define INST_PTR_REG eip --#endif -- --#endif -- --static uint64_t get_child_ip(pid_t childPid) --{ -- user_regs_struct regs = {}; -- -- iovec regs_iovec = {&regs, sizeof(regs)}; -- long ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); -- if(ptraceRet == 0) -- return uint64_t(regs.INST_PTR_REG); -- -- return 0; --} -- --static bool wait_traced_child(pid_t childPid, uint32_t timeoutMS, int &status) --{ -- // spin waiting for the traced child, with a 100ms timeout -- status = 0; -- uint64_t start_nano = get_nanotime(); -- uint64_t end_nano = 0; -- int ret = 0; -- -- const uint64_t timeoutNanoseconds = uint64_t(timeoutMS) * 1000 * 1000; -- -- while((ret = waitpid(childPid, &status, WNOHANG)) == 0) -- { -- status = 0; -- -- // if we're in a capturing process then the process itself might have done waitpid(-1) and -- // swallowed the wait for our child. So as an alternative we check to see if we can query the -- // instruction pointer, which is only possible if the child is stopped. -- uint64_t ip = get_child_ip(childPid); -- if(ip != 0) -- { -- // do waitpid again in case we raced and the child stopped in between the call to waitpid and -- // get_child_ip. -- ret = waitpid(childPid, &status, WNOHANG); -- -- // if it still didn't succeed, set status to 0 so we know we're earlying out and don't check -- // the status codes. -- if(ret == 0) -- status = 0; -- return true; -- } -- -- usleep(10); -- -- // check the timeout -- end_nano = get_nanotime(); -- if(end_nano - start_nano > timeoutNanoseconds) -- break; -- } -- -- return WIFSTOPPED(status); --} -- - bool StopChildAtMain(pid_t childPid, bool *exitWithNoExec) - { -- // don't do this unless the ptrace scope is OK. -- if(!ptrace_scope_ok()) -- return false; -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Stopping child PID %u at main", childPid); -- -- int childStatus = 0; -- -- // we have a low timeout for this stop since it should happen almost immediately (right after the -- // fork). If it didn't then we want to fail relatively fast. -- if(!wait_traced_child(childPid, 100, childStatus)) -- { -- RDCERR("Didn't get initial stop from child PID %u", childPid); -- return false; -- } -- -- if(childStatus > 0 && WSTOPSIG(childStatus) != SIGSTOP) -- { -- RDCERR("Initial signal from child PID %u was %x, expected %x", childPid, WSTOPSIG(childStatus), -- SIGSTOP); -- return false; -- } -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Child PID %u is stopped in StopAtMainInChild()", childPid); -- -- int64_t ptraceRet = 0; -- -- // continue until exec -- ptraceRet = ptrace(PTRACE_SETOPTIONS, childPid, NULL, PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Child PID %u configured to trace exec(). Continuing child", childPid); -- -- // continue -- ptraceRet = ptrace(PTRACE_CONT, childPid, NULL, NULL); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- // we're not under control of when the application calls exec() after fork() in the case of child -- // processes, so be a little more generous with the timeout -- if(!wait_traced_child(childPid, 250, childStatus)) -- { -- RDCERR("Didn't get to execve in child PID %u", childPid); -- return false; -- } -- -- int statusResult = childStatus >> 8; -- -- if(childStatus > 0 && -- (statusResult == SIGCHLD || statusResult == (SIGTRAP | (PTRACE_EVENT_EXIT << 8)))) -- { -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Child PID %u exited while waiting for exec() 0x%x", childPid, childStatus); -- if(exitWithNoExec) -- *exitWithNoExec = true; -- -- if(statusResult == SIGCHLD) -- ptrace(PTRACE_DETACH, childPid, NULL, SIGCHLD); -- else -- ptrace(PTRACE_DETACH, childPid, NULL, NULL); -- return false; -- } -- -- if(childStatus > 0 && statusResult != (SIGTRAP | (PTRACE_EVENT_EXEC << 8))) -- { -- RDCERR("Exec wait event from child PID %u was status 0x%x, expected 0x%x", childPid, -- statusResult, (SIGTRAP | (PTRACE_EVENT_EXEC << 8))); -- -- return false; -- } -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Child PID %u is stopped at execve() 0x%x", childPid, childStatus); -- -- rdcstr exepath; -- long baseVirtualPointer = 0; -- uint32_t sectionOffset = 0; -- -- rdcstr mapsName = StringFormat::Fmt("/proc/%u/maps", childPid); -- -- FILE *maps = FileIO::fopen(mapsName, FileIO::ReadText); -- -- if(!maps) -- { -- RDCERR("Couldn't open %s", mapsName.c_str()); -- return false; -- } -- -- while(!feof(maps)) -- { -- char line[512] = {0}; -- if(fgets(line, 511, maps)) -- { -- if(strstr(line, "r-xp")) -- { -- RDCCOMPILE_ASSERT(sizeof(long) == sizeof(void *), "Expected long to be pointer sized"); -- int pathOffset = 0; -- int num = sscanf(line, "%lx-%*x r-xp %x %*x:%*x %*u %n", &baseVirtualPointer, -- &sectionOffset, &pathOffset); -- -- if(num != 2 || pathOffset == 0) -- { -- RDCERR("Couldn't parse first executable mapping '%s'", rdcstr(line).trimmed().c_str()); -- return false; -- } -- -- exepath = line + pathOffset; -- exepath.trim(); -- break; -- } -- } -- } -- -- if(baseVirtualPointer == 0) -- { -- RDCERR("Couldn't find executable mapping in maps file"); -- return false; -- } -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Child PID %u has exepath %s basePointer 0x%llx and sectionOffset 0x%x", childPid, -- exepath.c_str(), (uint64_t)baseVirtualPointer, (uint32_t)sectionOffset); -- -- FileIO::fclose(maps); -- -- FILE *elf = FileIO::fopen(exepath, FileIO::ReadText); -- -- if(!elf) -- { -- RDCERR("Couldn't open %s to parse ELF header", exepath.c_str()); -- return false; -- } -- -- Elf64_Ehdr elf_header; -- size_t read = FileIO::fread(&elf_header, sizeof(elf_header), 1, elf); -- -- if(read != 1) -- { -- FileIO::fclose(elf); -- RDCERR("Couldn't read ELF header from %s", exepath.c_str()); -- return false; -- } -- -- size_t entryVirtual = (size_t)elf_header.e_entry; -- // if the section doesn't shift between file offset and virtual address this will be the same -- size_t entryFileOffset = entryVirtual; -- -- if(elf_header.e_shoff) -- { -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("exepath %s contains sections, rebasing to correct section", exepath.c_str()); -- -- FileIO::fseek64(elf, elf_header.e_shoff, SEEK_SET); -- -- RDCASSERTEQUAL(elf_header.e_shentsize, sizeof(Elf64_Shdr)); -- -- for(Elf64_Half s = 0; s < elf_header.e_shnum; s++) -- { -- Elf64_Shdr section_header; -- read = FileIO::fread(&section_header, sizeof(section_header), 1, elf); -- -- if(read != 1) -- { -- FileIO::fclose(elf); -- RDCERR("Couldn't read section header from %s", exepath.c_str()); -- return false; -- } -- -- if(section_header.sh_addr <= entryVirtual && -- entryVirtual < section_header.sh_addr + section_header.sh_size) -- { -- if(Linux_Debug_PtraceLogging()) -- RDCLOG( -- "Found section in %s from 0x%llx - 0x%llx at offset 0x%llx containing entry 0x%llx.", -- exepath.c_str(), (uint64_t)section_header.sh_addr, -- uint64_t(section_header.sh_addr + section_header.sh_size), -- (uint64_t)section_header.sh_offset, (uint64_t)entryVirtual); -- -- entryFileOffset = -- (entryVirtual - (size_t)section_header.sh_addr) + (size_t)section_header.sh_offset; -- -- break; -- } -- } -- } -- -- FileIO::fclose(elf); -- -- void *entry = (void *)(baseVirtualPointer + entryFileOffset - sectionOffset); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("child process %u executable %s has entry %p at 0x%llx + (0x%llx - 0x%x)", childPid, -- exepath.c_str(), entry, (uint64_t)baseVirtualPointer, (uint64_t)entryFileOffset, -- (uint32_t)sectionOffset); -- -- // this reads a 'word' and returns as long, upcast (if needed) to uint64_t -- uint64_t origEntryWord = (uint64_t)ptrace(PTRACE_PEEKTEXT, childPid, entry, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Read word %llx from %p in child process %u running executable %s", -- (uint64_t)origEntryWord, entry, childPid, exepath.c_str()); -- -- uint64_t breakpointWord = -- (origEntryWord & (0xffffffffffffffffULL << (BREAK_INST_BYTES_SIZE * 8))) | BREAK_INST; -- // downcast back to long, if that means truncating -- ptraceRet = ptrace(PTRACE_POKETEXT, childPid, entry, (long)breakpointWord); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Changed word to %llx and re-poked in process %u. Continuing child", -- (uint64_t)breakpointWord, childPid); -- -- // continue -- ptraceRet = ptrace(PTRACE_CONT, childPid, NULL, NULL); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- // it could take a long time to hit main so we have a large timeout here -- if(!wait_traced_child(childPid, 2000, childStatus)) -- { -- RDCERR("Didn't hit breakpoint in PID %u (%x)", childPid, childStatus); -- return false; -- } -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Process %u hit entry point", childPid); -- -- // we're now at main! now just need to clean up after ourselves -- -- user_regs_struct regs = {}; -- -- iovec regs_iovec = {&regs, sizeof(regs)}; -- ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Process %u instruction pointer is at %llx, for entry point %p", childPid, -- (uint64_t)(regs.INST_PTR_REG), entry); -- -- // step back past the byte(s) we inserted the breakpoint on -- regs.INST_PTR_REG -= BREAK_INST_INST_PTR_ADJUST; -- ptraceRet = ptrace(PTRACE_SETREGSET, childPid, (void *)NT_PRSTATUS, &regs_iovec); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- // restore the function -- ptraceRet = ptrace(PTRACE_POKETEXT, childPid, entry, origEntryWord); -- RDCASSERTEQUAL(ptraceRet, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Process %u instruction pointer adjusted and breakpoint removed.", childPid); -- -- // we'll resume after reading the ident port in the calling function -- return true; -+ int stat; -+ pid_t pid; -+ pid = waitpid(childPid, &stat, WUNTRACED); -+ return pid == childPid && WIFSTOPPED(stat); - } - --void StopAtMainInChild() -+void ResumeProcess(pid_t childPid, uint32_t delay = 0) - { -- // don't do this unless the ptrace scope is OK. -- if(!ptrace_scope_ok()) -- return; -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Stopping in main at child for ptracing"); -- -- // allow parent tracing, and immediately stop so the parent process can attach -- ptrace(PTRACE_TRACEME, 0, 0, 0); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Done PTRACE_TRACEME, raising SIGSTOP"); -- -- raise(SIGSTOP); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Resumed after SIGSTOP"); -+ kill(childPid, SIGCONT); - } - --void ResumeProcess(pid_t childPid, uint32_t delaySeconds) -+void StopAtMainInChild(void) - { -- if(!ptrace_scope_ok()) -- return; -- -- if(childPid != 0) -- { -- // if we have a delay, see if the process is paused. If so then detach it but keep it stopped -- // and wait to see if someone attaches -- if(delaySeconds > 0) -- { -- uint64_t ip = get_child_ip(childPid); -- -- if(ip != 0) -- { -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Detaching %u with SIGSTOP to allow a debugger to attach, waiting %u seconds", -- childPid, delaySeconds); -- -- // detach but stop, to allow a debugger to attach -- ptrace(PTRACE_DETACH, childPid, NULL, SIGSTOP); -- -- rdcstr filename = StringFormat::Fmt("/proc/%u/status", childPid); -- -- uint64_t start_nano = get_nanotime(); -- uint64_t end_nano = 0; -- -- const uint64_t timeoutNanoseconds = uint64_t(delaySeconds) * 1000 * 1000 * 1000; -- -- bool connected = false; -- -- // watch for a tracer to attach -- do -- { -- usleep(10); -- -- rdcstr status; -- FileIO::ReadAll(filename, status); -- -- int32_t offs = status.find("TracerPid:"); -- -- if(offs < 0) -- break; -- -- status.erase(0, offs + sizeof("TracerPid:")); -- status.trim(); -- -- end_nano = get_nanotime(); -- -- if(status[0] != '0') -- { -- RDCLOG("Debugger PID %u attached after %f seconds", atoi(status.c_str()), -- double(end_nano - start_nano) / 1000000000.0); -- connected = true; -- break; -- } -- } while(end_nano - start_nano < timeoutNanoseconds); -- -- if(!connected) -- { -- RDCLOG("Timed out waiting for debugger, resuming"); -- kill(childPid, SIGCONT); -- } -- return; -- } -- else -- { -- RDCERR("Can't delay for debugger without ptrace, check ptrace_scope value"); -- } -- } -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Detaching immediately from %u", childPid); -- -- // try to detach and resume the process, ignoring any errors if we weren't tracing -- long ret = ptrace(PTRACE_DETACH, childPid, NULL, NULL); -- -- if(Linux_Debug_PtraceLogging()) -- RDCLOG("Detached pid %u (%ld)", childPid, ret); -- } -+ raise(SIGSTOP); - } - - // because OSUtility::DebuggerPresent is called often we want it to be -diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp -index 01cc81c8a9..a99d924ec0 100644 ---- a/renderdoc/os/posix/posix_process.cpp -+++ b/renderdoc/os/posix/posix_process.cpp -@@ -606,9 +606,6 @@ static pid_t RunProcess(rdcstr appName, rdcstr workDir, const rdcstr &cmdLine, c - childPid = fork(); - if(childPid == 0) - { -- if(pauseAtMain) -- StopAtMainInChild(); -- - FileIO::ReleaseFDAfterFork(); - if(stdoutPipe) - { diff --git a/.config/sys/etc/portage/patches/media-gfx/renderdoc/no-execinfo.patch b/.config/sys/etc/portage/patches/media-gfx/renderdoc/no-execinfo.patch @@ -1,21 +0,0 @@ -diff --git a/renderdoc/os/posix/linux/linux_callstack.cpp b/renderdoc/os/posix/linux/linux_callstack.cpp -index f0b44b0..558765d 100644 ---- a/renderdoc/os/posix/linux/linux_callstack.cpp -+++ b/renderdoc/os/posix/linux/linux_callstack.cpp -@@ -27,7 +27,6 @@ - #define _GNU_SOURCE - #endif - --#include <execinfo.h> - #include <link.h> - #include <stdio.h> - #include <string.h> -@@ -66,7 +65,7 @@ private: - { - void *addrs_ptr[ARRAY_COUNT(addrs)]; - -- int ret = backtrace(addrs_ptr, ARRAY_COUNT(addrs)); -+ int ret = 0; - - numLevels = 0; - if(ret > 0)