weblist output disassembly now contains inlined source. (#235)
weblist output disassembly now contains inlined source.
In addition, fixed the line number assigned to instructions from inlined calls.
As an illustration, see the before and after output for a "pprof -weblist" command for a simple function:
[before](https://ghemawat.github.io/scratch/tmp/list1.html)
[after](https://ghemawat.github.io/scratch/tmp/list2.html)
Note that in the "before" page, the 7.26 second line cannot be expanded, but in the "after" page clicking on it reveals a wealth of information.
Use common header for remaining web views (source code, disassembly, peek) (#214)
Use common header for remaining web views (source code, disassembly, peek).
Details:
* Made it easier to reuse css, javascript, etc. across views.
* Added two new templates: sourcelisting, plaintext.
* Use new templates for showing source code, disassembly, peek.
* Merged Functions menu into View menu.
* View change menu entries are now always enabled.
* Removed now unused "newWindow" argument to navigate.
* Removed redundancy in web handlers.
* Renamed /weblist URL to /source.
* Assembly and source code listings are now limited to 500 functions
sorted by decreasing flat value (to prevent huge delays when
selecting asm/source view across the entire profile).
* Align file names in weblist disassembly
The disassembly displayed by weblist attempts to align file:line
information after each instruction, but two things interfere with this
alignment: 1) the instruction text often has tabs in it, which defeats
the length-based alignment and generally interacts poorly with HTML
rendering and 2) the instruction text often has special HTML
characters like < and > in it, but we pad the string after escaping
it, so the length is again not representative of how it will display.
For example, the following shows what this looks like for disassembly
that contains < and >:
. . 41c634: cmp $0x200,%rdx mgcsweepbuf.go:130
. . 41c63b: jae 41c64f <runtime.(*gcSweepBuf).pop+0x4f> mgcsweepbuf.go:130
. . 41c63d: mov (%rax,%rdx,8),%rcx mgcsweepbuf.go:130
. . 41c64f: callq 424800 <runtime.panicindex> mgcsweepbuf.go:130
. . 41c654: ud2 mgcsweepbuf.go:130
Fix these problems by replacing tab characters with spaces and padding
the string before escaping it. After this, the file names are properly
aligned:
. . 41c634: cmp $0x200,%rdx mgcsweepbuf.go:130
. . 41c63b: jae 41c64f <runtime.(*gcSweepBuf).pop+0x4f> mgcsweepbuf.go:130
. . 41c63d: mov (%rax,%rdx,8),%rcx mgcsweepbuf.go:130
. . 41c64f: callq 424800 <runtime.panicindex> mgcsweepbuf.go:130
. . 41c654: ud2 mgcsweepbuf.go:130
* Separate discontiguous assembly blocks
Currently, weblist's disassembled output for each line simply lists
all instructions that are marked with that line number. This leads to
confusing disassembly because a lot of things look like straight-line
control flow when they aren't. For example, index panics look like
they always happen:
. . 41c62c: test %al,(%rax)
. . 41c62e: and $0x1ff,%edx
. . 41c634: cmp $0x200,%rdx
. . 41c63b: jae 41c64f <runtime.(*gcSweepBuf).pop+0x4f>
. . 41c63d: mov (%rax,%rdx,8),%rcx
. . 41c64f: callq 424800 <runtime.panicindex>
. . 41c654: ud2
In reality, 41c64f is at the end of the function, but it looks like we
call it immediately after a successful index operation.
Fix this by adding a vertical ellipses to separate blocks of assembly
that have other instructions between them. With this change, the above
looks like:
. . 41c62c: test %al,(%rax)
. . 41c62e: and $0x1ff,%edx
. . 41c634: cmp $0x200,%rdx
. . 41c63b: jae 41c64f <runtime.(*gcSweepBuf).pop+0x4f>
. . 41c63d: mov (%rax,%rdx,8),%rcx
⋮
. . 41c64f: callq 424800 <runtime.panicindex>
. . 41c654: ud2
*: golint, go tool vet, unsued, gosimple, staticcheck (#113)
* `git ls-files -- '*.go' | xargs gofmt -s -w`
* driver: unexport InternalOptions
This was an exported method that returned an internal type, so it's
unlikely that anyone depends on its presence.
* internal/binutils: remove newline in error string
golint reported: error strings should not be capitalized or end with
punctuation or a newline
* internal/driver: s/buildId/buildID/ per golint
* internal/elfexec: remove punctuation in error string
golint reported: error strings should not be capitalized or end with
punctuation or a newline
* internal/graph: correct comment
Found with golint.
* internal/graph: add method comment
golint reported: exported method Edge.WeightValue should have comment
or be unexported
* internal/report: remove newline in error string
golint reported: error strings should not be capitalized or end with
punctuation or a newline
* *: remove unused code
Found with honnef.co/go/tools/cmd/unused:
internal/binutils/disasm_test.go:137:8: const objdump is unused (U1000)
internal/driver/driver_test.go:353:6: type testProfile is unused (U1000)
internal/graph/graph.go:838:6: func countEdges is unused (U1000)
profile/proto.go:148:6: func encodeStringOpt is unused (U1000)
* *: simply code
Found with honnef.co/go/tools/cmd/gosimple:
internal/driver/commands.go:471:24: should omit comparison to bool constant, can be simplified to !b (S1002)
internal/driver/driver.go:163:5: should omit comparison to bool constant, can be simplified to !trim (S1002)
internal/driver/driver.go:168:5: should omit comparison to bool constant, can be simplified to !focus (S1002)
internal/driver/driver.go:172:5: should omit comparison to bool constant, can be simplified to !tagfocus (S1002)
internal/driver/driver.go:176:5: should omit comparison to bool constant, can be simplified to !hide (S1002)
internal/graph/dotgraph.go:213:34: should use make(map[string][]*Tag) instead (S1019)
internal/report/report.go:1061:3: should replace loop with label = append(label, rpt.options.ProfileLabels...) (S1011)
profile/proto.go:157:5: should omit comparison to bool constant, can be simplified to !x (S1002)
* *: correct mistakes
Found with honnef.co/go/tools/cmd/staticcheck:
driver/driver.go:280:20: infinite recursive call (SA5007)
internal/driver/driver_focus.go:54:11: this value of err is never used (SA4006)
profile/proto.go:74:32: x | 0 always equals x (SA4016)
* Add linters to .travis.yml
Disassembly reports generated by pprof -disasm will now include line number
information as generated by objdump. This will make the generated assembly more
readable.
As part of this I've introduced a new assemblyInstruction struct. Previously
the code was reusing the graph.Node to represent assembly instructions but it
seems better to have a dedicated type for this.
When generating callgrind format output, produce cost lines at
instruction granularity. This allows visualizers supporting the
callgrind format to display instruction-level profiling information.
We also need to provide the object file (ob=) in order for tools to find
the object file to disassemble when displaying assembly.
We opportunistically group cost lines corressponding to the same
function together, reducing the number of superfluous description lines.
Subposition compression (relative position numbering) is also used to
reduce the output size.
This is to keep the new TrimTree functionality from breaking any code
currently using the public interface. We do this by separating NodeSet
from nodePtrSet and creating different functions for each.
Allow weblist to work even if assembly is not available
Weblist provides source and assembly combined in a web document.
It needs access to the binary to print the assembly, but currently
refuses to generate the source if the binary can't be find.
Fall back to just generating the source if the binary isn't found.
Add source_path option to point pprof to source files
Currently pprof will look for source files only on the current directory
and its parents. This makes it hard to examine sources on jobs where
there are multiple source trees (eg from different libraries).
Add a variable to provide a search path for source files. It will default
to the cwd, so there will be no change in behavior by default.