Skip to content

Conversation

@bobrik
Copy link
Contributor

@bobrik bobrik commented Dec 30, 2025

As discussed in facebook/dns#116, this adds a Go library in the same repo as blazesym itself.

I only added two methods for the symbolizer: one for pid based resolution and one for ELF based one. There's also a cli tool that I used to compare against blazecli. The output seems to match. The README explains how to build this.

I think it's reasonable to start with this small API surface area and then expand to more of it later.

If this makes sense, I can add tests and general CI scaffolding. Let me know if there's anything else you'd like to see before this is good to merge.

@codecov
Copy link

codecov bot commented Dec 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.73%. Comparing base (035b712) to head (af54fa6).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1402      +/-   ##
==========================================
- Coverage   95.85%   95.73%   -0.12%     
==========================================
  Files          61       61              
  Lines       11076    11076              
==========================================
- Hits        10617    10604      -13     
- Misses        459      472      +13     

☔ 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.

Copy link
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! Overall this looks mostly good to me. Left a first set of comments. Let me know what you think. Will probably give it another pass early next year.

I believe the current setup of requiring manual installation + flags setting etc. is probably fairly cumbersome for users, but we can revisit this down the line.

The one thing I think we will need is tests for the bindings and then hook that up to CI. This doesn't have to be super comprehensive, but at last something like

/// Check that we can symbolize addresses inside our own process.
#[test]
fn symbolize_process() {

/// Check that we "fail" symbolization as expected on a stripped ELF
/// binary.
#[tag(other_os)]
#[test]
fn symbolize_elf_stripped() {

A simplified ELF + DWARF variation of:

/// Check that we can symbolize an address using ELF, DWARF, and GSYM.
#[tag(other_os)]
#[test]
fn symbolize_elf_dwarf_gsym() {

I think it's fine to rely on the Rust created test binaries. You can create them using cargo check --package blazesym-dev --features=generate-unit-test-files.

Let me know if you need help with any of that.

go/symbolizer.go Outdated
}

func (s *Symbolizer) processSyms(syms *C.blaze_syms, stack []uint64) ([]Sym, error) {
lastErr := BlazeErr(C.blaze_err_last())
Copy link
Collaborator

Choose a reason for hiding this comment

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

This pattern of checking last error here seems dangerous, as there is no guarantee that syms hasn't been stored anywhere and other blazesym calls have happened in between. I'd rather we move this check to the call site.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an internal helper that is not a part of accessible API.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand that, but that only makes it marginally better, in my opinion. Anyway, it's not super critical.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It feels wrong to me to add duplicate error handling in each processSyms caller.

@@ -0,0 +1,145 @@
package main
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd really not want to have a CLI like this floating around, as it will cause confusion with the Rust one. Can we make this an example of sorts instead? I.e., move it into the newly created examples/ or so and then adjust the README accordingly.

Personally I'd also rather split it into two examples, one for process symbolization and one for ELF stuff and then provide suitable example inputs that "just work", but it's not a must.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved it to an example. This is how it looks like locally with go doc -C go -http:

image

@bobrik bobrik force-pushed the ivan/go branch 8 times, most recently from f76c3c3 to 615ac6d Compare December 31, 2025 06:23
@bobrik
Copy link
Contributor Author

bobrik commented Dec 31, 2025

I believe the current setup of requiring manual installation + flags setting etc. is probably fairly cumbersome for users, but we can revisit this down the line.

It's what libbpfgo does and I use it in my own ebpf_exporter to provide both static and dynamic builds. It is fully transparent if the library is installed in the regular system paths.

The trouble with all the env variables comes when the C library is not installed globally, so you have to tell the C compiler and the linker where the things are. I'm not aware of a way to make Go toolchain compile a C library for you and use that transparently.

The one thing I think we will need is tests for the bindings and then hook that up to CI. This doesn't have to be super comprehensive, but at last something like

I added the tests you mentioned and hooked them up to CI and it only took 7 attempts to get it right!

image

Copy link
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.

Looks great to me now, thanks! One last comment below.

Also, I am curious why did you opt to make blazeErr internal only? I guess it's fine to just work with error, but it would seem good to have the additional info that the error code provides available in general.

@d-e-s-o
Copy link
Collaborator

d-e-s-o commented Jan 2, 2026

I just noticed that CI also prints this warning:

Restore cache failed: Dependencies file is not found in /home/runner/work/blazesym/blazesym. Supported file pattern: go.sum

Is this something we can address easily by any chance or is that just inherent given how we do things?

@bobrik bobrik force-pushed the ivan/go branch 2 times, most recently from e447e16 to 84779da Compare January 2, 2026 21:59
Signed-off-by: Ivan Babrou <github@ivan.computer>
@bobrik
Copy link
Contributor Author

bobrik commented Jan 2, 2026

Also, I am curious why did you opt to make blazeErr internal only? I guess it's fine to just work with error, but it would seem good to have the additional info that the error code provides available in general.

I'm not using the error for anything other than to bail and I think it would be best to make it public when there's a clear user need for it. That way if I mess things up it won't be a breaking change.

I just noticed that CI also prints this warning:

Restore cache failed: Dependencies file is not found in /home/runner/work/blazesym/blazesym. Supported file pattern: go.sum

Is this something we can address easily by any chance or is that just inherent given how we do things?

I tried fixing it by adding the following:

cache-dependency-path: go/go.sum

But then it hit me that we don't have go.sum because we don't have dependencies.

@bobrik
Copy link
Contributor Author

bobrik commented Jan 2, 2026

Let me know if I missed anything. I tested it manually with a patched Grafana Alloy and it looks right:

image

@d-e-s-o
Copy link
Collaborator

d-e-s-o commented Jan 3, 2026

Seems all fine to me now, thanks again!

@d-e-s-o d-e-s-o merged commit 7b3ccd3 into libbpf:main Jan 3, 2026
45 checks passed
@bobrik bobrik deleted the ivan/go branch January 6, 2026 19:23
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