Hi all,
We’re seeing a reproducible segfault in an OpenACC (nvfortran) application
that only occurs on an 8x A100-SXM4 NVSwitch system (AWS p4d.24xlarge),
while the exact same build runs fine on single-GPU T4 and L4 instances.
Posting here in case anyone has seen something similar, or can point us
toward what to check next.
== Environment (crashing system) ==
- AWS EC2 p4d.24xlarge (Tokyo region)
- OS: Red Hat Enterprise Linux 9.7, kernel 5.14.0-687.10.1.el9_8.x86_64
- GPU: 8x NVIDIA A100-SXM4-40GB
- GPU Addressing Mode: HMM (per `nvidia-smi -q`)
- NVIDIA Driver: 610.43.02, CUDA 12.4 (UMD 13.3)
- NVIDIA HPC SDK: nvfortran 24.9, OpenMPI 4.1.5 (bundled with NVHPC 24.9)
- MIG: disabled via `sudo nvidia-smi -mig 0`
- Relevant build flags: -acc -gpu=cc75,cc80,cc90,mem:separate -cuda -O3 -traceback -tp=host
== Symptom ==
Even with `mpiexec -np 1`, the process crashes immediately at startup,
before main()/MPI_Init:
Caught signal 11 (Segmentation fault: address not mapped to object at address 0x13)
libacchost.so(__pgi_uacc_register_static+0x3c)
The exact same build works correctly on:
- g4dn.4xlarge (Tesla T4)
- g6.4xlarge (NVIDIA L4)
== What we’ve ruled out ==
Can’t reproduce on our own single-GPU dev box (A30, no NVSwitch) even
with every variable aligned to the customer’s environment (exact driver
version, NVHPC version, HMM addressing mode, driver flavor). Individually
tested and eliminated: NVHPC/driver version mismatches, mpiexec/libmpi
version mismatches, MPI transport (ucx vs ob1), multi-rank+MPS sharing a
GPU, CUDA_VISIBLE_DEVICES edge cases, -gpu=managed vs mem:separate (no
effect either way), two independently-built official release binaries.
All crash-free on single GPU. Leading hypothesis is GPU count/NVSwitch
topology, but that’s process-of-elimination, not a confirmed mechanism.
== What we found from static analysis ==
The faulting instruction (`__pgi_uacc_register_static+0x3c` in
libacchost.so) is `mov 0x10(%r14),%rbp`. %r14 holds the function’s 5th
argument per the x86-64 calling convention. 0x3 + 0x10 = 0x13 matches
the reported fault address exactly, so the 5th arg is effectively `0x3`
at crash time — a small invalid integer, not a dangling pointer.
Traced the actual caller (a `.init_array` entry, confirmed via gdb `bt`
with no intermediate frame): it loads the 5th arg with
`mov $0x1a85b80,%r8d` — a **hardcoded absolute immediate baked into the
instruction bytes**, pointing at a fixed global (`__PGI_CUDA_LOC`, a
40-byte `void*[5]` table whose first entry points into `.nv_fatbin`).
Confirmed the binary is `ET_EXEC` (not PIE) and `readelf -r` shows zero
relocations for this symbol — so this isn’t a relocation/ASLR failure
either. On paper this instruction can’t produce anything but 0x1a85b80.
We also confirmed the real CUDA device-enumeration path
(`__pgi_uacc_cuda_init_framework`) hasn’t run yet at the point of the
crash, and checked libcuda.so/libmpi.so/libcudart.so for any early
constructor-time logic that could touch shared state before this point
— nothing found in any of them.
== Question ==
Has anyone seen a case where a fixed immediate-load instruction like
this ends up with a wrong value in the destination register at the
point of use, specifically on multi-GPU NVSwitch systems that doesn’t
reproduce on single-GPU boxes? We’re struggling to find a mechanism
that would touch a callee-saved register or a process’s own .text page
this early (before main(), before any CUDA device enumeration) in a way
that’s specific to GPU count/topology.
Also since the crash appears to be in generic compiler-generated
registration infrastructure rather than anything specific to our
application logic, we’d expect even a minimal OpenACC “hello world”
(a single trivial `!$acc kernels` region) built with the same NVHPC
version to crash the same way on this hardware. Has anyone tried
something that minimal on a multi-GPU NVSwitch system? We plan to test
this ourselves but don’t yet have access to matching hardware.
Happy to provide `nm`/`objdump`/gdb output, full build flags, or
anything else that would help narrow this down.
Thanks!