-
Notifications
You must be signed in to change notification settings - Fork 316
interpreter: add Golang #408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
5ad982b
to
9078329
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments added. But before just blindly starting mixing Rust, I'd like a larger discussion a comments from all maintainers on feasibility of this.
I understand using existing Rust code might be faster, and the Rust code is likely good and tested.
On the other hand this the down sides are:
- core maintainers should also know Rust (possibly true?)
- CGO is slower than regular Go calls. not sure of the overhead.
- there is room for non-trivial errors as the calls need to use unsafe Go, potentially in non-trivial ways
Additionally go symbolization could be done directly using Go standard runtime libraries, or by extending the existing elfgopclntab code we have intree.
Could you elaborate why embedded Rust was chosen instead of the two above mentioned approaches? Do these reasons justify the overhead that mixing Go and Rust brings both in maintanenance, complexity and debugging?
Besides the main reasons you outlined (Rust code performant/safe/well tested), using Regardless, I'm not opposed to doing Go symbolization in Go, assuming someone implements it we could evaluate and transition. But we don't have that right now (and at least at Elastic, have no plans to work on it) and we do have |
If going this way, I'd rather then use
Also looking at Rust code a bit, it seems to IMHO the |
That is the general idea going forward. At the moment the scope is limited and focused on Go as from this ecosystem there is the highest demand for Symbols. |
interpreter/golang/golang.go
Outdated
} | ||
|
||
frameID := libpf.NewFrameID(libpf.NewFileID(uint64(frame.File), uint64(frame.File)), | ||
libpf.AddressOrLineno(symbolsSlice[0].line_number)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched the AddressOrLineno part of frameID with 5bf7fd7. Previously pc was used, but this generated too much different frame IDs for the same function/source file/source line combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does prevent using the data for PGO. Do you have statistics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't collect statistics. Like everywhere else for the on CPU sampling approach, leave frames are different which causes a high number of variance and differences in frame IDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some additional new comments to clean up a bit.
Also, how much the profiler executable size goes up with this now that it pulls static Rust stuff?
interpreter/golang/golang.go
Outdated
frameID := libpf.NewFrameID(libpf.NewFileID(uint64(frame.File), uint64(frame.File)), | ||
libpf.AddressOrLineno(symbolsSlice[0].line_number)) | ||
|
||
trace.AppendFrameID(libpf.GolangFrame, frameID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this provide the mapping information similar as the non-symbolized native code is done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point Go frames are treated as interpreter and no longer as native code. So I guess the answer here is no, and mapping information is not provided similar to other native code.
interpreter/golang/golang.go
Outdated
} | ||
|
||
frameID := libpf.NewFrameID(libpf.NewFileID(uint64(frame.File), uint64(frame.File)), | ||
libpf.AddressOrLineno(symbolsSlice[0].line_number)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does prevent using the data for PGO. Do you have statistics?
A little note that also #407 adds |
|
3222c8d
to
9a26452
Compare
Force pushed to resolve merge conflict with |
8be0993
to
9a26452
Compare
Another potential downside is the use of malloc. Some implementations are known to not return the freed memory to the OS. Some implementations keep the freed memory in per thread arenas. This may lead to increased memory consumption, which may be amplified by the number of threads the cgo call was issued from (consider a cgo call allocates a total of 10Mib in small chunks. If we have multiple of these calls from different goroutines (and therefor threads - we do not control the thread by default)) and if we have 32 threads, eventually we may waste 320Mib. It's possible to mitigate by locking the goroutine-thread. Nothing unsolvable, just something to keep in mind. |
interpreter/go/go.go
Outdated
symbolsSlice := unsafe.Slice((*C.SymblibResolvedSymbol)(unsafe.Pointer(symbols.data)), | ||
symbols.len) | ||
if len(symbolsSlice) != 1 { | ||
return fmt.Errorf("unexpected return for point lookup: %d", len(symbolsSlice)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 1? Does it not resolve inlined functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - inlined functions are not resolved atm.
Signed-off-by: Florian Lehner <[email protected]>
Co-authored-by: Timo Teräs <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
Signed-off-by: Florian Lehner <[email protected]>
df97089
to
dbc4130
Compare
Signed-off-by: Florian Lehner <[email protected]>
dbc4130
to
733570f
Compare
PR has been rebased on current friendly ping for feedback @fabled && @christos68k |
Signed-off-by: Florian Lehner <[email protected]>
ac92755
to
b93d090
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. We can revisit later if using debug/gosym
is feasible when the other prerequisites for it are done first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
I also tested locally and everything works as expected. I'm assuming the crashes you saw on your send were not related to pinning (otherwise they'd also manifest for me and @fabled) and I'm also assuming you can no longer trigger them on your end.
Signed-off-by: Florian Lehner <[email protected]>
## Summary OTel Semantic Conventions [defines](open-telemetry/semantic-conventions#2003) a type for Go and OTel eBPF profiler is about to start with pushing Go frames (either with open-telemetry/opentelemetry-ebpf-profiler#409 or open-telemetry/opentelemetry-ebpf-profiler#408) FYI: @elastic/ingest-otel-data ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] ~~Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)~~ not relevant - [ ] ~~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials~~ not relevant - [ ] ~~[Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios~~ not relevant - [ ] ~~If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~ not relevant - [ ] ~~This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations.~~ not relevant - [ ] ~~[Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed~~ not relevant - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - `release_note:skip` Signed-off-by: Florian Lehner <[email protected]> (cherry picked from commit 7c4af05)
# Backport This will backport the following commits from `main` to `8.19`: - [[Profiling] Add FrameType and color for Go (#215697)](#215697) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Florian Lehner","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-03-24T15:05:07Z","message":"[Profiling] Add FrameType and color for Go (#215697)\n\n## Summary\n\nOTel Semantic Conventions\n[defines](https://github.com/open-telemetry/semantic-conventions/pull/2003)\na type for Go and OTel eBPF profiler is about to start with pushing Go\nframes (either with\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/409\nor\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/408)\n\nFYI: @elastic/ingest-otel-data \n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] ~~Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)~~\nnot relevant\n- [ ]\n~~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials~~ not\nrelevant\n- [ ] ~~[Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios~~ not relevant\n- [ ] ~~If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~\nnot relevant\n- [ ] ~~This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.~~\nnot relevant\n- [ ] ~~[Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed~~ not relevant\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- `release_note:skip`\n\nSigned-off-by: Florian Lehner <[email protected]>","sha":"7c4af051b22c64fae5ad532be25080152293446e","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:skip","Team:obs-ux-infra_services","v9.1.0"],"title":"[Profiling] Add FrameType and color for Go","number":215697,"url":"https://github.com/elastic/kibana/pull/215697","mergeCommit":{"message":"[Profiling] Add FrameType and color for Go (#215697)\n\n## Summary\n\nOTel Semantic Conventions\n[defines](https://github.com/open-telemetry/semantic-conventions/pull/2003)\na type for Go and OTel eBPF profiler is about to start with pushing Go\nframes (either with\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/409\nor\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/408)\n\nFYI: @elastic/ingest-otel-data \n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] ~~Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)~~\nnot relevant\n- [ ]\n~~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials~~ not\nrelevant\n- [ ] ~~[Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios~~ not relevant\n- [ ] ~~If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~\nnot relevant\n- [ ] ~~This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.~~\nnot relevant\n- [ ] ~~[Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed~~ not relevant\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- `release_note:skip`\n\nSigned-off-by: Florian Lehner <[email protected]>","sha":"7c4af051b22c64fae5ad532be25080152293446e"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/215697","number":215697,"mergeCommit":{"message":"[Profiling] Add FrameType and color for Go (#215697)\n\n## Summary\n\nOTel Semantic Conventions\n[defines](https://github.com/open-telemetry/semantic-conventions/pull/2003)\na type for Go and OTel eBPF profiler is about to start with pushing Go\nframes (either with\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/409\nor\nhttps://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/408)\n\nFYI: @elastic/ingest-otel-data \n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] ~~Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)~~\nnot relevant\n- [ ]\n~~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials~~ not\nrelevant\n- [ ] ~~[Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios~~ not relevant\n- [ ] ~~If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~~\nnot relevant\n- [ ] ~~This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.~~\nnot relevant\n- [ ] ~~[Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed~~ not relevant\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- `release_note:skip`\n\nSigned-off-by: Florian Lehner <[email protected]>","sha":"7c4af051b22c64fae5ad532be25080152293446e"}}]}] BACKPORT--> Signed-off-by: Florian Lehner <[email protected]> Co-authored-by: Florian Lehner <[email protected]>
Add symbolization functionality for Go executables.