blob: 13d68b15e4ff4df927df2332deccc8e969552df9 [file] [log] [blame] [view]
Fergal Daly21879c062018-10-16 07:30:311# Dumping the compiled code from a chrome binary
2
John Palmer046f9872021-05-24 01:24:563[Rendered](https://chromium.googlesource.com/chromium/src/+/main/docs/disassemble_code.md)
Fergal Dalyff6d4d582019-08-28 22:21:204
Fergal Daly21879c062018-10-16 07:30:315## Background
6
7Sometimes you want to look at the disassembled code of a method,
8e.g. you have a stack trace like
9
10```
110xd3c90a78(libmonochrome.so -vector.h:1047 ) blink::EventDispatcher::Dispatch()
120xde86db5a
130xd3c8fcdd(libmonochrome.so -event_dispatcher.cc:59 )blink::EventDispatcher::DispatchEvent(blink::Node&, blink::Event*)
14```
15
16Where something from `vector.h` has been inlined in `Dispatch()`
17and so you don't know what line in of `Dispatch()` is actually crashing.
18Or you want to compare the code before and after a "no-op" change
19that has resulted in a perf regression
20or you want to see what methods have been inlined in the final binary
21(e.g. AFDO can result in more/less inlining,
22depending what was observed when the AFDO data was collected).
23
24This doc tells you how to dump the assembly for a method
25and how to deal with stack traces involving inlined code.
26
27## Differences for Googlers
28
29There are some tasks,
30like disassembling official release builds of chrome
31that have Google-specific instructions.
32You can find them [here](https://goto.google.com/disassemble-chrome-code)
33
34## Building an unstripped binary
35
36Below are the ninja arguments for the `rel_ng` trybot
37but with extra symbols enabled.
38We can include even more symbols with `symbol_level` of `2` instead of `1`
39but the binary size is much greater.
40
41```
42is_official_build = true
43dcheck_always_on = true
44is_component_build = false
45is_debug = false
Fergal Daly21879c062018-10-16 07:30:3146blink_symbol_level = 1
47symbol_level = 1
48
49# Restricted options. May not make sense for non-Googlers.
50use_goma = true
51proprietary_codecs = true
52ffmpeg_branding = "Chrome"
53```
54
55This should be close to a release-optimized binary
56e.g. it applies Automatic Feedback Directed Optimization.
57You might want to switch to `dcheck_always_on=false`.
58
59To build, run
60
61```shell
62ninja -C out/RelNgSym
63```
64
65You probably will want to add some more command line options to this,
66depending on your usual build paralellism.
67
68## Getting the right objdump
69
70You can dump the asm from the binary or `.so` file using `objdump`.
71You can dump the symbols using `nm`.
72Both are from GNU binutils.
73For x86 code, if you are running Linux,
74you probably have it already.
75
76If you are trying to examine Android code,
77it's likely ARM or MIPS.
78In that case you can install an alternate binutils package
79or (maybe better) use the one that ships in Android's SDK.
80
81## Finding the address of the compiled code
82
83So, let's say we are looking for `blink::StyleInvalidator::Invalidate`.
84First we dump out the symbols from the binary.
85This takes a few seconds.
86
87```shell
88nm out/RelNgSym/chrome > /tmp/symbols
89```
90
91Now we need to get the start and end address of the function.
92This is a little hacky but we can find the end address
93by finding the next function
94(with symbol level `2` we get entries
95which give an address and length
96but nm is slower).
97So now run
98
99```shell
100grep -A1 "blink::StyleInvalidator::Invalidate(" /tmp/symbols
101```
102
103and you should see the something like
104
105```
106000000000769d230 t blink::StyleInvalidator::Invalidate(blink::Element&, blink::StyleInvalidator::SiblingData&)
107000000000769ce10 t blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)
108000000000769d950 t blink::StyleInvalidator::SiblingData::MatchCurrentInvalidationSets(blink::Element&, blink::StyleInvalidator&)
109```
110
111So we have found 2 overloads for this symbol
112and let's say we want the latter.
113So the function starts at `0x769ce10`
114and ends at `0x769d950`
115(the address of the next symbol).
116
117## Dumping code
118
119Using the relevant objdump binary, we can now dump the assembly code with
120
121```
122objdump -j .text -D -l -C --start-addr=0x769ce10 --stop-addr=0x769d950 out/RelNgSym/chrome
123```
124
125and you get something like
126
127```
128out/RelNgSym/chrome: file format elf64-x86-64
129
130
131Disassembly of section .text:
132
133000000000769ce10 <blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)>:
134_ZN5blink16StyleInvalidator10InvalidateERNS_8DocumentEPNS_7ElementE():
135./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.cc:31
136 769ce10: 55 push %rbp
137 769ce11: 48 89 e5 mov %rsp,%rbp
138 769ce14: 41 57 push %r15
139 769ce16: 41 56 push %r14
140 769ce18: 41 55 push %r13
141 769ce1a: 41 54 push %r12
142 769ce1c: 53 push %rbx
143 769ce1d: 48 81 ec 28 01 00 00 sub $0x128,%rsp
144 769ce24: 49 89 d4 mov %rdx,%r12
145 769ce27: 49 89 f7 mov %rsi,%r15
146 769ce2a: 49 89 fe mov %rdi,%r14
147 769ce2d: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
148 769ce34: 00 00
149 769ce36: 48 89 45 d0 mov %rax,-0x30(%rbp)
150InlineBuffer():
151./../../third_party/blink/renderer/platform/wtf/vector.h:864
152 769ce3a: 4c 8d ad c8 fe ff ff lea -0x138(%rbp),%r13
153VectorBufferBase():
154./../../third_party/blink/renderer/platform/wtf/vector.h:465
155 769ce41: 4c 89 ad b8 fe ff ff mov %r13,-0x148(%rbp)
156 769ce48: 48 c7 85 c0 fe ff ff movq $0x10,-0x140(%rbp)
157 769ce4f: 10 00 00 00
158SiblingData():
159./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.h:87
160 769ce53: c7 45 c8 00 00 00 00 movl $0x0,-0x38(%rbp)
161GetFlag():
162./../../third_party/blink/renderer/core/dom/node.h:909
163 769ce5a: 8b 46 10 mov 0x10(%rsi),%eax
164 769ce5d: 66 85 c0 test %ax,%ax
165_ZN5blink16StyleInvalidator10InvalidateERNS_8DocumentEPNS_7ElementE():
166./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.cc:34
167 769ce60: 0f 88 28 01 00 00 js 769cf8e <blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)+0x17e>
168./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.cc:41
169 769ce66: 4d 85 e4 test %r12,%r12
170 769ce69: 0f 84 85 00 00 00 je 769cef4 <blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)+0xe4>
171 769ce6f: 48 8d 95 b8 fe ff ff lea -0x148(%rbp),%rdx
172./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.cc:42
173 769ce76: 4c 89 f7 mov %r14,%rdi
174 769ce79: 4c 89 e6 mov %r12,%rsi
175 769ce7c: e8 af 03 00 00 callq 769d230 <blink::StyleInvalidator::Invalidate(blink::Element&, blink::StyleInvalidator::SiblingData&)>
176IsEmpty():
177./../../third_party/blink/renderer/platform/wtf/vector.h:1039
178 769ce81: 83 bd c4 fe ff ff 00 cmpl $0x0,-0x13c(%rbp)
179_ZN5blink16StyleInvalidator10InvalidateERNS_8DocumentEPNS_7ElementE():
180./../../third_party/blink/renderer/core/css/invalidation/style_invalidator.cc:43
181 769ce88: 74 56 je 769cee0 <blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)+0xd0>
182 769ce8a: 4c 89 e3 mov %r12,%rbx
183 769ce8d: 0f 1f 00 nopl (%rax)
184 769ce90: 48 8b 5b 30 mov 0x30(%rbx),%rbx
185NextSibling():
186./../../third_party/blink/renderer/core/dom/element_traversal.h:530 (discriminator 2)
187 769ce94: 48 85 db test %rbx,%rbx
188 769ce97: 74 47 je 769cee0 <blink::StyleInvalidator::Invalidate(blink::Document&, blink::Element*)+0xd0>
189
190...
191```
192
193
194## Further reading
195
John Palmer046f9872021-05-24 01:24:56196https://chromium.googlesource.com/chromium/src/+/main/docs/linux/minidump_to_core.md#Source-debugging
Fergal Daly21879c062018-10-16 07:30:31197
198https://www.chromium.org/developers/how-tos/debugging-on-windows