From 437c3a6c160ecc6c8b3090bb6586f7243889b702 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 15 Aug 2026 23:37:01 +1000 Subject: [PATCH 1/2] autotest: find dumpstack.sh when not run from the repo root run_command_on_ownpid() looks for dumpstack.sh and dumpcore.sh relative to the working directory. A serial autotest run works because it runs in the repo root, but under --parallel each instance runs in its own directory, every lookup misses, and we fall back to trusting PATH - where the script is not. A panic there produced "Failed" and no backtrace at all, which is precisely when one is wanted. The AP_SCRIPTS_DIR_PATH override already existed, but the filepath was formed into a 60-byte buffer. An absolute path to a checkout overflows that easily - /home/user/rc/ardupilot-claude2/Tools/scripts/dumpstack.sh is 61 characters - and snprintf simply truncated, leaving a name which failed to stat, so the override looked as though it had been ignored. Size the buffer for a path, and skip any candidate which does not fit rather than stat'ing a truncated name. Co-Authored-By: Claude Opus 5 (1M context) --- Tools/autotest/pysim/util.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Tools/autotest/pysim/util.py b/Tools/autotest/pysim/util.py index 9992a1ec7b2f03..30366f7b01085b 100644 --- a/Tools/autotest/pysim/util.py +++ b/Tools/autotest/pysim/util.py @@ -714,9 +714,16 @@ def start_SITL(binary, first = cmd[0] rest = cmd[1:] - spawn_env = None + spawn_env = dict(os.environ) + # Tell SITL where to find dumpstack.sh and dumpcore.sh. It looks + # for them relative to its working directory, which works for a + # serial run - that runs in the repo root - but not under + # --parallel, where each instance runs in its own directory and + # every lookup misses. A panic there produces no backtrace at + # all, which is exactly when one is wanted. + spawn_env.setdefault('AP_SCRIPTS_DIR_PATH', + os.path.abspath(reltopdir('Tools/scripts'))) if asan: - spawn_env = dict(os.environ) log_base = asan_log_filepath(binary=binary, model=model) existing = spawn_env.get('ASAN_OPTIONS', '') # Append our options after any inherited ones so that our From 1473edb825054b2ef12c43a08e5d7e59e5d12896 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 15 Aug 2026 23:37:01 +1000 Subject: [PATCH 2/2] AP_HAL_SITL: find dumpstack.sh when not run from the repo root run_command_on_ownpid() looks for dumpstack.sh and dumpcore.sh relative to the working directory. A serial autotest run works because it runs in the repo root, but under --parallel each instance runs in its own directory, every lookup misses, and we fall back to trusting PATH - where the script is not. A panic there produced "Failed" and no backtrace at all, which is precisely when one is wanted. The AP_SCRIPTS_DIR_PATH override already existed, but the filepath was formed into a 60-byte buffer. An absolute path to a checkout overflows that easily - /home/user/rc/ardupilot-claude2/Tools/scripts/dumpstack.sh is 61 characters - and snprintf simply truncated, leaving a name which failed to stat, so the override looked as though it had been ignored. Size the buffer for a path, and skip any candidate which does not fit rather than stat'ing a truncated name. Co-Authored-By: Claude Opus 5 (1M context) --- libraries/AP_HAL_SITL/system.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libraries/AP_HAL_SITL/system.cpp b/libraries/AP_HAL_SITL/system.cpp index 5b8edd7a94778e..f0ca8f6ecb0acf 100644 --- a/libraries/AP_HAL_SITL/system.cpp +++ b/libraries/AP_HAL_SITL/system.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -75,14 +76,22 @@ static void run_command_on_ownpid(const char *commandname) "APM/Tools/scripts/%s", // for autotest server "../Tools/scripts/%s", // when run from e.g. ArduCopter subdirectory }; - char buffer[60]; + // long enough for an absolute path from AP_SCRIPTS_DIR_PATH; the 60 + // bytes this used to be was not - a checkout under a path of any + // length silently truncated, and the truncated name simply failed to + // stat, so the override looked as though it had been ignored + char buffer[PATH_MAX]; for (uint8_t i=0; i= sizeof(buffer)) { + // truncated, so this is not the path we were asked for + continue; + } if (::stat(buffer, &statbuf) != -1) { command_filepath = buffer; break; @@ -112,7 +121,9 @@ static void run_command_on_ownpid(const char *commandname) commandname, p+1, (int)getpid()); - char cmd[200]; + // must fit the command filepath found above, which may now be + // an absolute path, plus the output filepath + char cmd[PATH_MAX + sizeof(output_filepath) + 32]; snprintf(cmd, sizeof(cmd), "sh %s %d >%s 2>&1",