Skip to content

Resolve native symbols for containerized python applications#329

Open
pramodk wants to merge 1 commit into
bloomberg:mainfrom
pramodk:pramodk/container-native-symbols
Open

Resolve native symbols for containerized python applications#329
pramodk wants to merge 1 commit into
bloomberg:mainfrom
pramodk:pramodk/container-native-symbols

Conversation

@pramodk

@pramodk pramodk commented Jul 10, 2026

Copy link
Copy Markdown

Describe your changes

This change fixes native symbol lookup for Python processes running inside container runtimes such as Enroot.

When the libdwfl lookup cannot open an absolute module path from /proc/<pid>/maps, this PR now retries that same path through the target process root:

  /proc/<pid>/root/<mapped-path>

The fallback is only used after build-id lookup and normal host path lookup fail, so existing host behavior remains unchanged.

Fixes #327.

Testing performed

  • Built a PyStack wheel from this PR.
  • Validated with a standalone ctypes repro:
    • Host process: upstream and patched PyStack resolve Python and native frames.
    • Enroot process with current main: Python frames are visible, native symbol is missing.
    • Enroot process with this PR: Python frames are visible, native symbol is resolved.

Additional context

The issue is specific to native C/C++ symbol lookup. Python frames can still be visible because PyStack can inspect the target process, but native library paths from /proc/<pid>/maps may exist only inside the container filesystem. As containers are used extensively in certain domains like AI/ML/Data Science, it would be really helpful to fix this.

- Add a libdwfl fallback that opens absolute module paths through /proc/<pid>/root so remote Pyxis/Enroot targets can resolve libraries that are only visible inside the container filesystem.
- Associate the analyzed PID with each DWFL module before attach so the ELF lookup callback can find the target process root during native unwinding.
- Preserve the existing build-id and linux-proc lookup paths first; the process-root fallback is used only when normal host lookup fails.
- This fixes the behavior seen with the ImageNet Pyxis NCCL run where PyStack 1.6 reported insufficient native information or lost libtorch/libtorch_cuda/NCCL frames from container targets.
@pramodk pramodk force-pushed the pramodk/container-native-symbols branch 2 times, most recently from 9558b20 to 695ff34 Compare July 10, 2026 09:26
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 42.10526% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.81%. Comparing base (4d4ef00) to head (695ff34).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/pystack/_pystack/elf_common.cpp 42.10% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #329      +/-   ##
==========================================
- Coverage   77.93%   77.81%   -0.13%     
==========================================
  Files          56       56              
  Lines        5988     6005      +17     
  Branches      631      637       +6     
==========================================
+ Hits         4667     4673       +6     
- Misses       1321     1332      +11     
Flag Coverage Δ
cpp 77.81% <42.10%> (-0.13%) ⬇️
python 77.81% <42.10%> (-0.13%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +73 to +75
if (ret < 0) {
ret = find_elf_through_proc_pid_root(userdata, modname, file_name);
}

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.

This only falls back to checking through /proc/$pid/root if the lookup on the host filesystem failed, but that seems wrong to me - isn't it possible that we've found entirely the wrong file if we looked on the host filesystem first? I would think that we'd want to always go through /proc/$pid/root whenever the mount namespace doesn't match. Or always, really? I can't think of any reason we wouldn't want to always resolve relative to it...

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.

In fact, I wonder whether this is something we should be implementing in pystack at all. Perhaps libdwfl should automatically be using /proc/$pid/root whenever it resolves files from /proc/$pid/map...

@godlygeek

Copy link
Copy Markdown
Contributor

This will definitely need an automated integration test added to the test suite, also!

@pramodk pramodk force-pushed the pramodk/container-native-symbols branch 2 times, most recently from 2e21b43 to 32d6854 Compare July 14, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve native symbols for containerized Python processes using the target process root (via /proc/<pid>/root)

3 participants