Skip to content

io: dlopen libbz2 by versioned SONAME, not unversioned symlink#1297

Merged
rapids-bot[bot] merged 1 commit into
release/26.06from
fix-libbz2-dlopen-soname
May 26, 2026
Merged

io: dlopen libbz2 by versioned SONAME, not unversioned symlink#1297
rapids-bot[bot] merged 1 commit into
release/26.06from
fix-libbz2-dlopen-soname

Conversation

@rgsl888prabhu
Copy link
Copy Markdown
Collaborator

@rgsl888prabhu rgsl888prabhu commented May 26, 2026

Issue

The release/26.06 container nightly CLI test fails on the .lp.bz2 case:

----------------- CLI TEST START ---------------
Expected solution not found for .lp.bz2
Error: Process completed with exit code 1.

(e.g. https://github.com/NVIDIA/cuopt/actions/runs/26435964807/job/77827519723#step:5:1291)

Root cause

cpp/src/io/file_to_string.cpp dlopens libbz2 by its unversioned name:

dlopen("libbz2.so", RTLD_LAZY)

On Debian/Ubuntu, the unversioned libbz2.so symlink only ships with the libbz2-dev package. The runtime package (libbz2-1.0, pulled in transitively by bzip2) provides only libbz2.so.1.0 / libbz2.so.1. So dlopen returns null, the .bz2 read aborts with "Could not open .bz2 file...", and the CLI test grep miss surfaces as "Expected solution not found for .lp.bz2".

.lp.gz works in the same container because the zlib code path already uses the versioned SONAME: dlopen("libz.so.1", RTLD_LAZY).

Fix

Mirror the zlib pattern. Try names in decreasing specificity and use the first that loads:

  1. libbz2.so.1.0 — bzip2 upstream's stable SONAME (objdump -p confirms; unchanged across all 1.0.x releases for ~20 years)
  2. libbz2.so.1 — symlink commonly shipped alongside .so.1.0
  3. libbz2.so — last resort, dev-only symlink

A future libbz2 2.x with SONAME libbz2.so.2.0 would (correctly) fail to load — it would be an ABI break anyway, same as the existing zlib behavior.

🤖 Generated with Claude Code

dlopen("libbz2.so", ...) requires the unversioned symlink, which on
Debian/Ubuntu ships only with libbz2-dev. The runtime package
(libbz2-1.0, pulled in by bzip2) provides libbz2.so.1.0 but not the
.so symlink, so the dlopen returns null and any .bz2 read fails with
"Could not open .bz2 file...". This breaks the release/26.06 container
nightly CLI test on the .lp.bz2 case while .lp.gz works, because the
zlib path already uses the versioned SONAME (libz.so.1).

Mirror the zlib pattern: try libbz2.so.1.0 (bzip2 upstream SONAME for
all 1.0.x releases), then libbz2.so.1, then libbz2.so as a last
resort. First successful dlopen wins.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
@rgsl888prabhu rgsl888prabhu requested a review from a team as a code owner May 26, 2026 16:15
@rgsl888prabhu rgsl888prabhu self-assigned this May 26, 2026
@rgsl888prabhu rgsl888prabhu added bug Something isn't working non-breaking Introduces a non-breaking change improvement Improves an existing functionality and removed bug Something isn't working labels May 26, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5635aee4-2922-4f8b-b837-fa4418eb3d8d

📥 Commits

Reviewing files that changed from the base of the PR and between a995424 and a744084.

📒 Files selected for processing (1)
  • cpp/src/io/file_to_string.cpp

📝 Walkthrough

Walkthrough

This PR enhances the dynamic loading of libbz2 in the file decompression utility. The change replaces a single attempt to load libbz2.so with a loop that tries multiple SONAME candidates (libbz2.so.1.0, libbz2.so.1, libbz2.so), improving cross-platform compatibility. The failure message is updated to report all attempted names.

Changes

bzip2 SONAME Loading Enhancement

Layer / File(s) Summary
Multi-candidate SONAME loading for libbz2
cpp/src/io/file_to_string.cpp
Dynamic library loading now iterates through multiple libbz2 SONAME candidates instead of trying only libbz2.so, with an updated failure message listing all attempted library names.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested labels

non-breaking, improvement

Suggested reviewers

  • hlinsen
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: updating bzip2 library loading to use versioned SONAMEs instead of an unversioned symlink.
Description check ✅ Passed The description is directly related to the changeset, providing clear context about the issue, root cause, and solution being implemented in the code changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-libbz2-dlopen-soname

Comment @coderabbitai help to get the list of available commands and usage tips.

@rgsl888prabhu
Copy link
Copy Markdown
Collaborator Author

/merge

@rapids-bot rapids-bot Bot merged commit 48893a0 into release/26.06 May 26, 2026
103 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants