Skip to content

capi: Add callback for symbolizer#1535

Open
sensille wants to merge 1 commit intolibbpf:mainfrom
sensille:symbolizer
Open

capi: Add callback for symbolizer#1535
sensille wants to merge 1 commit intolibbpf:mainfrom
sensille:symbolizer

Conversation

@sensille
Copy link
Copy Markdown
Contributor

Expose parts of set_process_dispatcher in the capi to enable users to provide alternative ELF file paths for symbolization (e.g., fetched via debuginfod).

As discussed in #1443.

Please let me know if this goes in the direction you had in mind.

Expose parts of set_process_dispatcher in the capi to enable users
to provide alternative ELF file paths for symbolization (e.g.,
fetched via debuginfod).

Signed-off-by: Arne Jansen <arne@die-jansens.de>
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.52%. Comparing base (675e5bf) to head (501ba9d).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1535      +/-   ##
==========================================
+ Coverage   95.48%   95.52%   +0.03%     
==========================================
  Files          56       56              
  Lines        9555     9555              
==========================================
+ Hits         9124     9127       +3     
+ Misses        431      428       -3     

☔ View full report in Codecov by Sentry.
📢 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.

@d-e-s-o d-e-s-o self-requested a review April 15, 2026 17:45
@d-e-s-o d-e-s-o self-assigned this Apr 15, 2026
Copy link
Copy Markdown
Collaborator

@d-e-s-o d-e-s-o left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request! Left a few comments. Can you check what you think?

Comment thread capi/src/symbolize.rs
/// the underlying language does not mangle symbols (such as C).
pub demangle: bool,
/// Explicit pad to avoid implicit gaps.
pub _pad_a: [u8; 4],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we rename this to _reserved1 or so?

Comment thread capi/src/symbolize.rs
/// languages are Rust and C++ and the flag will have no effect if
/// the underlying language does not mangle symbols (such as C).
pub demangle: bool,
/// Explicit pad to avoid implicit gaps.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you please make it clear that this should be initialized to zero like other unused fields?

Comment thread capi/src/symbolize.rs
/// Unused member available for future expansion. Must be initialized
/// to zero.
pub reserved: [u8; 20],
pub reserved: [u8; 24],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think the size of the struct should stay constant. So we should decrease instead of increase. It's a bit annoying that this change alone brings us to the limit, basically. Perhaps we'd should just embed a single pointer to a struct containing the two pointers in question...? Given that it's a niche case and can be stack allocated, it's probably okay, would be my take.

Comment thread capi/src/symbolize.rs

let builder = if let Some(cb) = process_dispatch_cb {
// Cast the context pointer to usize so the closure is Send.
// The caller is responsible for thread safety of the context.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Okay, but that should be mentioned in the corresponding part of the documentation then, I'd say.

Comment thread capi/src/symbolize.rs
// NUL-terminated, `malloc`'d C string.
let path_cstr = unsafe { CStr::from_ptr(result) };
let path = Path::new(OsStr::from_bytes(path_cstr.to_bytes()));
let resolver = ElfResolver::open(path);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This constructor doesn't honor any custom debug directories that may have been configured. I feel like this can be confusing to users relying on that.

Copy link
Copy Markdown
Contributor Author

@sensille sensille Apr 17, 2026

Choose a reason for hiding this comment

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

I see. I also found that the caching behavior is different, it cannot de-duplicate between processes anymore if I read this correctly. so how do we solve this? I see

  1. Just document the behavior.
  2. Add another constructor to ElfResolver that also passes debug_dirs and leave caching as-is.
  3. Somehow pass the path back to the symbolizer and let it construct the resolver the same way it would without the dispatch callback. This would handle both issues.

I find 3 to be the most appealing, but also the most intrusive. What do you think?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah, I think the caching story is unfortunate but non-trivial to solve. Given that it's not really a correctness issue, I'd say we leave it as-is. For debug_dirs, I think an additional constructor for ElfResolver is fine.

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.

2 participants