Granulate / gprofiler

gProfiler is a system-wide profiler, combining multiple sampling profilers to produce unified visualization of what your CPU is spending time on.
https://profiler.granulate.io
Apache License 2.0
749 stars 54 forks source link

Identify golang binaries w/o requiring symbols #817

Closed Jongy closed 1 year ago

Jongy commented 1 year ago

With https://github.com/Granulate/gprofiler/issues/804 we now collect stripped / not strpped for golang. This is not proving useful because we IDENTFIY golang processes using symbols, so obv, if a program is strpped, it is not considered golang (that stripped my mind).

Our goal with https://github.com/Granulate/gprofiler/issues/804 is still to be able to tell for a golang program if it's stripped or not (because it happens often and then the user needs to rebuild it with symbols). For this purpose I want us to switch identification so it doesn't depend on symbols.

I don't have a concrete idea but I suppose that searching for some magic strings / other details in the ELF might work.

Jongy commented 1 year ago

When you implement it, make sure to update the relevant README section here which claims that symbols are needed for identification.

Jongy commented 1 year ago

Before implementing please discuss your suggestions here.

marcin-ol commented 1 year ago

Golang binaries, even the stripped ones can be identified by ELF Note section note.go.buildid, unless intentionally transformed beyond recognition (e.g.: strip --remove).

Found this symbol in binaries built by golang versions 1.5 .. 1.20+:

$ grep . -r --include="elfheaders*" -Hne 'go.buildid'
./elfheaders-1.7.txt:47:  [11] .note.go.buildid
./elfheaders-1.20.txt:49:  [12] .note.go.buildid
./elfheaders-1.16.txt:49:  [12] .note.go.buildid
./elfheaders-1.8.txt:47:  [11] .note.go.buildid
./elfheaders-1.12.txt:47:  [11] .note.go.buildid
./elfheaders-1.5.txt:45:  [10] .note.go.buildid
./elfheaders-1.6.txt:45:  [10] .note.go.buildid

Support for this has been added in Golang 1.5. See references.

This works nicely and could be implemented in granulate-utils:

[2023-08-03 09:36:17,853] DEBUG: exe=/proc/318897/exe; found note: {'n_name': 'Go', 'n_desc': 'iET6gPjQs8_ercVKmI_5/V4ftLGgOIqqHxmcxKKUT/nXzOVLSE6qHN-pQLyuU-/iET6gPjQs8_ercVKmI_5'}

References: