Fix ELF base calculation for exec mapping with offset != 0. (#425)
I was looking at a report where pprof wouldn't symbolize the data
collected for a Chrome binary using Linux perf (b/112303003). The mmap
information is:
start: 0000000002, limit: 0000000006, offset: 0000000002
The ELF file header:
elf.FileHeader{Class:elf.ELFCLASS64, Data:elf.ELFDATA2LSB, Version:elf.EV_CURRENT, OSABI:elf.ELFOSABI_NONE, ABIVersion:0x0, ByteOrder:binary.LittleEndian, Type:elf.ET_EXEC, Machine:elf.EM_X86_64, Entry:0x272e000}
The code segment:
elf.ProgHeader{Type:elf.PT_LOAD, Flags:elf.PF_X+elf.PF_R, Off:0x252f000,
Vaddr:0x272e000, Paddr:0x272e000, Filesz:0x43da610, Memsz:0x43da610,
Align:0x1000}
The dynamic loader here mapped 0x6b09000-0x272e000 = 0x43db000 bytes
starting 0x252f000 file offset into 0x272e000 virtual address, exactly
as instructed by the program header (so, no ASLR). Thus, the base
adjustment should be zero. Yet, the current GetBase produced the base of
0x252f000 which is wrong. The reason for that is that the ET_EXEC branch
of GetBase doesn't handle the general case of non-zero mmap file offset,
but rather only supports a couple of special cases. This change makes
handling the case of user-mode ET_EXEC more generic.
Make '-noinlines' a separate flag, introduce '-filefunctions' granularity. (#420)
This change consists of two relatively independent parts, but they are
both about handling the granularity, so bundling them together.
First, in #415 there is a discussion that having a granularity mode by
source lines but with inlines hidden would be useful. The agreement is
also that adding `-linenoinlines` granularity would make the granularity
flags too messy (and they are already somewhat messy with `-addresses`
and `-addressnoinlines`. So, it was proposed to make `-noinlines` a
separate flag, which is what this change does. Note that the flag is now
pulled out of the granularity group so it's a bit of backward
incompatible change but I think it is acceptable. For the example in
issue #415 the user would now be able to specify `-list foo -noinlines`
to produce annotated source where the metrics from the inlined functions
are attributed to the calling inliner line.
With this change, I am also dropping the `-addressnoinlines` granularity
which is now supported as `-addresses -noinlines` combination. I
couldn't find any usage of this option at least internally at Google, so
I think it's safe to remove it.
Second, I am adding a separate `-filefunctions` granularity which groups
the data by both function and file. This is a follow-up to #110 from the
past where we changed the `-functions` granularity to not group by file
(it used to), and since then there was a couple of reports where using
just function name alone would over-aggregate the data in cases when a
function with the same name is contained in multiple source files (e.g.
see b/18874275 internally).
Also, make a number of assorted documentation and `-help` fixes.
This is a follow up change to #412 which adds a selector to the web
ui for selecting the sample index of a profile to view. The selector
is hidden for profiles with only a single sample type.
Add support for fat Mach-O files
Fixes #1033. Note that this does not do the "correct" thing, of checking the main executable to see what architecture it is and trying to match that. Or maybe checking the architecture in the profile file if it is present.
Instead it just uses the host architecture to decide which subfile of the fat archive to open.
Expose sample_index argument through web ui (#412)
The option is exposed in the web ui's query string under a
new `?si=<sample_index>` parameter. This is particularly
useful for heap profiles, where switching between the four
indices (alloc_objects, alloc_space, inuse_objects, and inuse_space)
is a common task.
We could add a menu to the UI to make discovery of these
options easier, but for now this seems sufficient.
Improve "unrecognized binary" error messages
Previously it would just print "unrecognized binary" no matter what the underlying error message was. This was partly because it was unable to know the actual file type except by trial and error. This commit uses the magic number instead. It also gives a nicer error for fat Mach-O binaries which are currently unsupported.
* make filters applied to -proto output
* update comments
* address comments
* reassign flags in TestParse
* update TestParse to address comments
* use original names for options in TestParse
Handle 64-bit negative addresses when adjusting them. (#397)
Fixes #280. 64-bit addresses with the high bit set should be adjustable
as long as the offset does not overflow the result. This change
supersedes #396 avoiding `math/big` dependency.
Force saving the module name for unsymbolized frames (#394)
Force saving the module name for unsymbolized frames
In some cases pprof isn't saving the module name in graph nodes, so
reports end up with nodes of the form '<unknown>'.
The module name is often stripped to allow symbolized frames from
different versions of a binary to be merge.
Force saving the objfile name if the name is unknown so we can print
some information for unsymbolized frames.
profile: fix legacy format Go heap profile parsing (#382)
This CL fixes a long-lasting bug that prevented pprof from recognizing
Legacy heap profile produced by Go. Go reports four types of samples
at once so the profile includes alloc_objects, alloc_space,
inuse_objects, and inuse_space. The bug caused pprof to misclassify Go
heap profile data and prevent selection of correct filtering/pruning
patterns in analysis.
Update golang/go#25096
Tested with the profile samples included in golang.org/issues/25096
(pprof hides the runtime functions with this change)
Add GetBase support for ASLR kernel mappings (#371)
Add GetBase support for kernel mappings as reported by Linux Perf
Linux Perf reports kernel mappings with an offset == start.
Currently GetBase() cannot handle such a case.
This behavior can be seen from a perf.report data with samples in the kernel:
$ sudo perf report -D perf.data | grep MMAP
0 0x108 [0x50]: PERF_RECORD_MMAP -1/0: [0xffffffffaf800000(0x1087a000) @ 0xffffffffaf800000]: x [kernel.kallsyms]_text
internal/driver: skip tests requiring tcp on js (#373)
This commit upstreams the changes made in golang.org/cl/110096. As the
change says, it is acceptable for the new js/wasm target to only support
what nacl supports right now.
Add "trim path" option which can be used to relocate sources. (#366)
Add "trim path" option which can be used to relocate sources.
When pprof is asked to show annotated source for a profile collected on
another machine for a Go program, the profile contains absolute paths
which may not exist on the local machine. In that case pprof currently
fails to locate the source with no option to help it. The new option
adds a way to specify one or several source path prefixes that should be
trimmed from the source paths in the profile before applying the search
using search path option.
For example, taking the example from the issue where the source file
path in the profile is
/home/teamcitycpp/agent09/work/56cbaf9067/_gopath/src/badoo/lakafka/main.go
and the local path is /home/marko/lakafka/main.go. The user may
specify
`-trim-path=/home/teamcitycpp/agent09/work/56cbaf9067/_gopath/src/badoo`
to make pprof find the source. The source path doesn't need to be
specified if the current working dir is anything at or under
`/home/marko/`.
When the trim path is not specified, it is guessed heuristically based
on the basename of configured searched paths. In the example above,
setting `-search-path=/home/marko/lakafka` would be sufficient to
activate the heuristic successfully. Or having the current directory as
`/home/marko/lakafka` since the search path is by default set to the
current working directory. Note that the heuristic currently
does not attempt to walk the configured search paths up like the search
does. This is to keep it simple, use `-trim-path` explicitly in more
complicated cases.
Fixes #262.
Add command-line editing support for interactive pprof (#362)
Add command-line editing support for interactive pprof
This implements basic command-line editing, using
github.com/chzyer/readline. This will not affect the golang
distribution as it uses its own pprof driver, with its own
driver.
Only tested on Linux.
TODO: Implement auto-completion and persistent history.
Update -help to list correct paths searched within PPROF_BINARY_PATH. (#355)
The code was updated in #335 but the doc wasn't updated. Also the doc
didn't include $path which is searched as well, see locateBinaries in
internal/driver/fetch.go.
Switch to use goroutine profile in TestHttpsInsecure. (#350)
Trying to test against /debug/pprof/profile has been giving some flakes
and trouble so far (#146, #253, #328, golang/go#24611, golang/go#22594). While
some of the discussions the failures triggered appear to be useful (such
as whether CPU profiles are expected to be working on Windows XP or
not), that kind of testing is not really in the scope for this
particular test. This change switches the test to use goroutine profile
instead which is hopefully much less dependent on the environment. The
change also makes the test much faster to run.
Previously, the web UI was hard-coded to be served at `/` but
applications which are *embedding* the ui are unlikely to host it there.
This change makes the links between the various ui pages relative,
addressing this problem.
To make sure this doesn't rot, the internal http server now serves the
ui at /ui/ (redirecting there from the root).
I think we can all agree that the ui code and JavaScript is kind of a
haphazard affair. I performed a great deal of clicking around to make
sure the semantics didn't change and interestingly spent some time
trying to fix semantics I later realized weren't actually there: I
thought that when navigating to another page from a focused search (say
`flamegraph?f=x`) the focus would be carried over. This doesn't seem to
be the case, however.
The point being, there's no test coverage and setting it up is way
beyond what I can do here. I'm happy to manually verify whatever
sequence of clicks is suggested, though.
Touches https://github.com/cockroachdb/cockroach/pull/24145.
This fixes a bug introduced in #341 which caused the browser
opening code to be disabled for the standard `pprof -http`
invocation.
Introduce a proper getter on the UI which determines whether
the browser ought to be opened.