Skip to content

[VL][CI] Fix Spark 4.1 CI crash: isolate libgluten's bundled libstdc++#12557

Merged
jackylee-ch merged 1 commit into
apache:mainfrom
jackylee-ch:fix-spark41-ci-centos8-crash
Jul 20, 2026
Merged

[VL][CI] Fix Spark 4.1 CI crash: isolate libgluten's bundled libstdc++#12557
jackylee-ch merged 1 commit into
apache:mainfrom
jackylee-ch:fix-spark41-ci-centos8-crash

Conversation

@jackylee-ch

@jackylee-ch jackylee-ch commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

The spark-test-spark41 / spark-test-spark41-slow jobs in Velox Backend (x86) have been failing consistently (exit 134 / SIGABRT) since the mid-July GitHub-hosted runner image rollout (tracked in #12534). The forked Surefire JVM crashes with SIGSEGV during Velox backend initialization, before the first native test (ColumnarBatchTest) even runs:

# C  [libgluten.so+0xdb73a4]  std::__codecvt_utf16_base<char16_t>::do_unshift(...)+0x4
# siginfo: si_code: SEGV_MAPERR, si_addr: 0x0000000000000030
Java frames:
 org.apache.gluten.init.NativeBackendInitializer.initialize(...)
 org.apache.gluten.backendsapi.velox.VeloxListenerApi.onExecutorStart(...)
 org.apache.gluten.test.VeloxBackendTestBase.setup()

Root cause (verified with readelf / addr2line on the CI artifact)

libgluten.so and libvelox.so both statically link the gcc-13 libstdc++ (dev/vcpkg/toolchain.cmake: -static-libstdc++ -static-libgcc).

  • libvelox has a local: * catch-all in its symbols.map, so its bundled libstdc++ symbols are demoted to STB_LOCAL and never take part in global symbol resolution.
  • libgluten cannot use local: * — it must keep Arrow/substrait exported for libvelox to link against — so its ~5000 bundled libstdc++ symbols stay in the dynamic symbol table. Critically, the std::locale::id objects that index the facet table are emitted as STB_GNU_UNIQUE.

Inside the centos-9 image, the JVM pulls in the system gcc-11 libstdc++.so.6.0.29. The dynamic loader collapses libgluten's STB_GNU_UNIQUE locale ids into a single process-wide definition, so libgluten indexes its own gcc-13 facet table with the wrong id, reads a bogus num_put/codecvt facet pointer, and dereferences null+0x30.

The older centos-8 system libstdc++ (gcc-8) is not new enough to interpose, which is exactly why only the centos-9 spark41 jobs crashed while spark33spark40 (centos-8), built from the very same native artifact, stayed green. This is not a code regression from any merged PR.

Fix

Pass -Wl,--exclude-libs for the bundled C++ runtime archives (libstdc++.a, libgcc.a, libgcc_eh.a) when linking libgluten. This demotes those symbols to STB_LOCAL — which also clears the STB_GNU_UNIQUE binding — giving libgluten the same self-contained libstdc++ isolation libvelox already has, without hiding the Arrow/substrait symbols libvelox resolves against.

-Bsymbolic alone does not work here, because STB_GNU_UNIQUE overrides it (verified in a separate CI run).

The CI workflow is unchanged — the Spark 4.1 jobs keep running on centos-9-jdk17. The fix is purely in the native link step, so it addresses the image itself rather than side-stepping it.

How was this patch tested?

Validated on a debug branch that trims the workflow to only the affected jobs and rebuilds the native libs with this change, keeping the container on centos-9-jdk17:

  • spark-test-spark41 — the SIGSEGV is gone; ColumnarBatchTest, arrow batched python udf over parquet scan, and the full backends-velox / gluten-ut suites run
  • spark-test-spark41-slowsuccess

Run: https://github.com/jackylee-ch/gluten/actions/runs/29676262109

Closes #12534

Copilot AI review requested due to automatic review settings July 18, 2026 15:44
@github-actions github-actions Bot added the INFRA label Jul 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the Velox backend (x86) GitHub Actions workflow to address consistent Spark 4.1 CI crashes occurring in the centos-9-jdk17 container by moving Spark 4.1 test jobs back to the centos-8-jdk17 image, and adds a Miniconda-based Python 3.11 setup for Spark 4.1 Python UDF requirements.

Changes:

  • Switch spark-test-spark41 and spark-test-spark41-slow jobs from apache/gluten:centos-9-jdk17 to apache/gluten:centos-8-jdk17.
  • Replace CentOS 9 dnf Python 3.11 installation with a Miniconda Python 3.11 install for the Spark 4.1 job prepare step.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/velox_backend_x86.yml Outdated
Comment on lines 1212 to 1219
curl -fsSL -o /tmp/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-py311_24.7.1-0-Linux-x86_64.sh && \
bash /tmp/miniconda.sh -b -p /opt/miniconda3 && \
ln -sf /opt/miniconda3/bin/python3.11 /usr/bin/python3 && \
ln -sf /opt/miniconda3/bin/pip3 /usr/bin/pip3 && \
python3 --version && \
pip3 install setuptools==77.0.3 && \
pip3 install pyspark==3.5.5 cython && \
pip3 install pandas==2.2.3 pyarrow==20.0.0

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved: this revision drops the miniconda approach entirely. The Spark 4.1 jobs stay on centos-9-jdk17 with the original dnf install python3.11 Prepare step (unchanged from main), so there is no longer any symlink mutation of /usr/bin/python3. The workflow file is now identical to main; the only change in this PR is the native link step in cpp/core/CMakeLists.txt.

Comment thread .github/workflows/velox_backend_x86.yml Outdated
Comment on lines +1212 to +1213
curl -fsSL -o /tmp/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-py311_24.7.1-0-Linux-x86_64.sh && \
bash /tmp/miniconda.sh -b -p /opt/miniconda3 && \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved: the miniconda download is gone in this revision. The Spark 4.1 jobs stay on centos-9-jdk17 and use the same dnf install python3.11 step as main, so there is no longer any curl|bash of an external installer. The only change in this PR is the native link step in cpp/core/CMakeLists.txt.

@philo-he

Copy link
Copy Markdown
Member

@jackylee-ch, do you mean CentOS-7-built Velox static lib hitting an incompatibility issue on Centos-9 at runtime? The apache/gluten:centos-9-jdk17 docker has been used for Spark 4.1 for a long time. Curious what Velox code changes make this issue happen recently.

The PR looks good as a quick fix. Not sure if we still have strong reason to use Centos 9 for Spark 4.1 tests (introduced by #11519). cc @zhouyuan

Copilot AI review requested due to automatic review settings July 19, 2026 09:27
@jackylee-ch
jackylee-ch force-pushed the fix-spark41-ci-centos8-crash branch from 0305186 to 757aca3 Compare July 19, 2026 09:27
@github-actions github-actions Bot added VELOX and removed INFRA labels Jul 19, 2026
@jackylee-ch jackylee-ch changed the title [VL][CI] Fix Spark 4.1 CI crash by moving tests back to CentOS 8 [VL][CI] Fix Spark 4.1 CI crash: isolate libgluten's bundled libstdc++ Jul 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@jackylee-ch

Copy link
Copy Markdown
Contributor Author

@philo-he It's not Velox code. libgluten's symbols.map has no local: *, so it exports its bundled gcc-13 libstdc++ symbols (locale facet ids/vtables) globally. When the process also loads the system gcc-11 libstdc++.so.6, those get interposed and the facet layout mismatches → crash. It's been latent; a recent image/runner change (system libstdc++ now new enough to interpose) exposed it. centos-8's older libstdc++ can't interpose, so it hid the bug.

I'm trying another way to fix the problem.

The spark-test-spark41 / spark-test-spark41-slow jobs have been failing
consistently (exit 134 / SIGABRT) since the mid-July GitHub runner image
rollout (tracked in apache#12534). The forked Surefire JVM crashes with SIGSEGV
during Velox backend initialization, before ColumnarBatchTest runs:

  C  [libgluten.so+0xdb73a4]  std::__codecvt_utf16_base<char16_t>::do_unshift...
  siginfo: SEGV_MAPERR, si_addr: 0x0000000000000030
  NativeBackendInitializer.initialize -> VeloxBackend::create

Root cause (verified with readelf/addr2line on the CI artifact):

libgluten.so and libvelox.so both statically link the gcc-13 libstdc++
(dev/vcpkg/toolchain.cmake: -static-libstdc++ -static-libgcc). libvelox's
symbols.map has a "local: *" catch-all, so its bundled libstdc++ symbols are
demoted to STB_LOCAL and never participate in global symbol resolution.
libgluten's symbols.map cannot use "local: *" -- it must keep Arrow/substrait
exported for libvelox -- so its ~5000 bundled libstdc++ symbols stay in the
dynamic symbol table, and the std::locale::id objects that index the facet
table are emitted as STB_GNU_UNIQUE.

Inside the centos-9 image the JVM pulls in the system gcc-11
libstdc++.so.6.0.29. The loader collapses libgluten's STB_GNU_UNIQUE locale
ids into a single process-wide definition, so libgluten indexes its gcc-13
facet table with the wrong id, reads a bogus num_put/codecvt facet pointer,
and dereferences null+0x30. The older centos-8 system libstdc++ (gcc-8) is not
new enough to interpose, which is why only the centos-9 spark41 jobs crashed
while spark33-40 (centos-8), built from the very same native artifact, stayed
green.

Fix: pass -Wl,--exclude-libs for the bundled C++ runtime archives when linking
libgluten, demoting those symbols to STB_LOCAL (which also clears the
STB_GNU_UNIQUE binding). This gives libgluten the same self-contained libstdc++
isolation libvelox already has, without hiding the Arrow/substrait symbols
libvelox resolves against. -Bsymbolic alone does not work because
STB_GNU_UNIQUE overrides it.

The CI workflow is unchanged: the Spark 4.1 jobs keep running on centos-9.

Co-Authored-By: Claude <noreply@anthropic.com>
@jackylee-ch
jackylee-ch force-pushed the fix-spark41-ci-centos8-crash branch from 757aca3 to 916dfbb Compare July 19, 2026 12:34
Copilot AI review requested due to automatic review settings July 19, 2026 12:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@jackylee-ch

jackylee-ch commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@philo-he @zhouyuan I would merge this for a quick fix, you can check and resolve it later.

@jackylee-ch
jackylee-ch merged commit 6fd6df3 into apache:main Jul 20, 2026
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[VL] Spark 4.1 CI intermittently aborts during Velox backend initialization

3 participants