Skip to content

chore(main): release 3.1.1#2

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main
Open

chore(main): release 3.1.1#2
github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main

Conversation

@github-actions

@github-actions github-actions Bot commented Feb 23, 2026

Copy link
Copy Markdown

🤖 I have created a release beep boop

3.1.1 (2026-02-26)

Bug Fixes

  • Fix crashes when calling sourcesAtFrame when clearing (#1122) (02a537b)
  • SG-42144: Fix off-by-one frame count error for audio-only files (#1068) (c4e0e15)
  • Use RV's python version to build wheels (#1009) (b5fa395)

Build System

GitHub Actions

  • Add semantic versioning for OpenRV to automate change logs and release (#1143) (42b3cd4)

This PR was generated with Release Please. See documentation.

@github-actions github-actions Bot force-pushed the release-please--branches--main branch from 7150fd8 to 06d0551 Compare February 26, 2026 16:12
bernie-laberge added a commit that referenced this pull request May 30, 2026
…ux 9 (part 2) (AcademySoftwareFoundation#1279)

### fix: SG-42890: Fix SIGSEGV error when running RVIO commands on Rocky
Linux 9 (part 2)

### Linked issues
NA

### Summarize your change.

Fix an `rvio` SIGSEGV that fires at shutdown on Linux with the NVIDIA
proprietary GL driver. Conversions complete successfully — the output
`.mov` is written intact — but the process then exits with a segfault,
which produces a crash dump and a non-zero exit code that breaks
RV/CI/render-farm pipelines.

Symptoms:
- All frames are rendered and the output file is fully written.
- The process then segfaults after `main()` returns.
- Crashpad-symbolicated minidump shows the crashing thread's `rip` in an
unmapped region with no usable call stack (only `stack scanning` frames
in
  `libc.so.6`). The crash address looks like garbage because the page is
  already gone by the time the dump is written.

Constant register signatures across ASLR-randomized runs (`rax=0x6e`,
`r14=0x1e8480`, `r15=0xfffffffffffffb28`) confirmed the crash always
lands at
the same instruction.

### Root cause

Captured under `gdb` (where the offending library is still mapped at the
instant of the SIGSEGV), the crashing thread is an NVIDIA driver
background
worker:

```
Thread N "RVIO Main" received signal SIGSEGV
0x00007fffcd9f59ec in ?? () from /lib64/libnvidia-glcore.so.595.58.03
#0  libnvidia-glcore.so.595.58.03
#1  libnvidia-glcore.so.595.58.03
#2  libnvidia-glcore.so.595.58.03
#3  start_thread () from libc.so.6
#4  clone3 () from libc.so.6
```

…while the main thread is mid-teardown:

```
#0  _dl_close_worker (...) at dl-close.c:769
#1  _dl_close
#2  __GI__dl_catch_exception
AcademySoftwareFoundation#5  dlclose@GLIBC_2.2.5 ()
AcademySoftwareFoundation#6  __glXMappingTeardown ()  from libGLX.so.0
AcademySoftwareFoundation#7  __glXFini ()             from libGLX.so.0
AcademySoftwareFoundation#8  _dl_fini ()              at dl-fini.c:148
AcademySoftwareFoundation#9  __run_exit_handlers ()   from libc.so.6
AcademySoftwareFoundation#10 exit ()                  from libc.so.6
```

This is the well-known **libglvnd ↔ NVIDIA driver shutdown race**:

1. `main()` returns.
2. libc's `exit()` runs `__run_exit_handlers` → `_dl_fini`.
3. `_dl_fini` invokes `libGLX.so.0`'s ELF destructor `__glXFini`, which
`dlclose`s the NVIDIA GLX vendor (`libGLX_nvidia.so.0`) and transitively
   unmaps `libnvidia-glcore.so`.
4. NVIDIA's proprietary driver maintains its own internal helper
threads. They
   are **not** joined by libglvnd's teardown — NVIDIA's blob has no such
   hook. The threads are still running when `dlclose` finishes.
5. The kernel unmaps `libnvidia-glcore.so`'s code pages out from under
one of
   those running threads → next instruction fetch hits unmapped memory →
   SIGSEGV.

The thread is named `"RVIO Main"` only because Linux child threads
inherit
their parent's `prctl(PR_SET_NAME)` value (set by
`TwkUtil::setThreadName`).
It is NOT the application's main thread.

By the time crashpad's signal handler finishes serializing the minidump,
`dlclose` has fully completed and the page is no longer in
`/proc/self/maps`,
which is why the dump appeared to crash "nowhere."

### Solution

`src/bin/imgtools/rvio/main.cpp`: on Linux, replace the final `return
0;`
in `utf8Main` with `std::_Exit(0);` — but only after all of rvio's
legitimate
shutdown has already run (`MovieRV::uninit`,
`TwkMovie::GenericIO::shutdown`, `TwkFB::GenericIO::shutdown`,
`TwkFB::ThreadPool::shutdown`).

`std::_Exit` is the POSIX "skip atexit / `_dl_fini` and terminate now"
primitive. It hands control directly to the kernel, which reaps memory,
file descriptors, and threads — including NVIDIA's straggler threads —
atomically, with no opportunity for the unload race.

Nothing in our shutdown is left undone:
- The output movie has already been finalized and `close`d by the writer
  before `utf8Main` reaches this point.
- All Open RV-owned plugins have been shut down explicitly above the
  `_Exit` call.

Windows and macOS still go through `return 0;` because they don't use
libglvnd and don't exhibit this race. The change is `#ifdef
PLATFORM_LINUX`
guarded.

Signed-off-by: Bernard Laberge <bernard.laberge@autodesk.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants