andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 1 | # Linux Profiling |
| 2 | |
qyearsley | c0dc6f4 | 2016-12-02 22:13:39 | [diff] [blame] | 3 | How to profile Chromium on Linux. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 4 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 5 | See |
| 6 | [Profiling Chromium and WebKit](https://sites.google.com/a/chromium.org/dev/developers/profiling-chromium-and-webkit) |
| 7 | for alternative discussion. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 8 | |
| 9 | ## CPU Profiling |
| 10 | |
| 11 | gprof: reported not to work (taking an hour to load on our large binary). |
| 12 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 13 | oprofile: Dean uses it, says it's good. (As of 9/16/9 oprofile only supports |
| 14 | timers on the new Z600 boxes, which doesn't give good granularity for profiling |
| 15 | startup). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 16 | |
| 17 | TODO(willchan): Talk more about oprofile, gprof, etc. |
| 18 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 19 | Also see |
| 20 | https://sites.google.com/a/chromium.org/dev/developers/profiling-chromium-and-webkit |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 21 | |
| 22 | ### perf |
| 23 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 24 | `perf` is the successor to `oprofile`. It's maintained in the kernel tree, it's |
| 25 | available on Ubuntu in the package `linux-tools`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 26 | |
| 27 | To capture data, you use `perf record`. Some examples: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 28 | |
| 29 | ```shell |
| 30 | # captures the full execution of the program |
| 31 | perf record -f -g out/Release/chrome |
| 32 | # captures a particular pid, you can start at the right time, and stop with |
| 33 | # ctrl-C |
| 34 | perf record -f -g -p 1234 |
| 35 | perf record -f -g -a # captures the whole system |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 36 | ``` |
| 37 | |
Daniel Cheng | 3e1b994 | 2024-03-01 18:36:08 | [diff] [blame] | 38 | > ⚠️ Note: on virtualized systems, e.g. cloudtops, the PMU counters may not |
| 39 | be available or may be broken. Use `-e cpu-clock` as a workaround. |
| 40 | Googlers, see [b/313526654](https://b.corp.google.com/issues/313526654). |
| 41 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 42 | Some versions of the perf command can be confused by process renames. Affected |
| 43 | versions will be unable to resolve Chromium's symbols if it was started through |
| 44 | perf, as in the first example above. It should work correctly if you attach to |
| 45 | an existing Chromium process as shown in the second example. (This is known to |
| 46 | be broken as late as 3.2.5 and fixed as early as 3.11.rc3.g36f571. The actual |
| 47 | affected range is likely much smaller. You can download and build your own perf |
| 48 | from source.) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 49 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 50 | The last one is useful on limited systems with few cores and low memory |
| 51 | bandwidth, where the CPU cycles are shared between several processes (e.g. |
| 52 | chrome browser, renderer, plugin, X, pulseaudio, etc.) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 53 | |
| 54 | To look at the data, you use: |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 55 | |
| 56 | perf report |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 57 | |
| 58 | This will use the previously captured data (`perf.data`). |
| 59 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 60 | ## Heap Profiling |
| 61 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 62 | #### Dumping a profile of a running process |
| 63 | |
Thiabaud Engelbrecht | 6d44361 | 2022-02-11 00:22:18 | [diff] [blame] | 64 | To programmatically generate a heap profile before exit, you can use gdb to |
| 65 | attach at any point: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 66 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 67 | 1. Attach gdb to the process: `$ gdb -p 12345` |
Thiabaud Engelbrecht | 6d44361 | 2022-02-11 00:22:18 | [diff] [blame] | 68 | 2. Cause it to dump a profile: `(gdb) p HeapProfilerDump("foobar")` |
| 69 | 3. The filename will be printed on the console you started Chrome from; e.g. |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 70 | "`Dumping heap profile to heap.0001.heap (foobar)`" |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 71 | |
| 72 | #### Analyzing dumps |
| 73 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 74 | You can then analyze dumps using the `pprof` script (distributed with |
| 75 | google-perftools, installed by default on Googler Linux workstations; on Ubuntu |
| 76 | it is called `google-pprof`). For example: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 77 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 78 | pprof --gv out/Release/chrome /tmp/heapprofile |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 79 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 80 | This will generate a visual representation of the heap profile as a postscript |
| 81 | file and load it up using `gv`. For more powerful commands, please refer to the |
| 82 | pprof help output and the google-perftools documentation. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 83 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 84 | (pprof is slow. Googlers can try the not-open-source cpprof; Evan wrote an open |
| 85 | source alternative [available on github](https://github.com/martine/hp).) |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 86 | |
| 87 | #### Sandbox |
| 88 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 89 | Sandboxed renderer subprocesses will fail to write out heap profiling dumps. To |
| 90 | work around this, turn off the sandbox (via `export CHROME_DEVEL_SANDBOX=`). |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 91 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 92 | #### More reading |
| 93 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 94 | For further information, please refer to |
| 95 | http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 96 | |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 97 | ## Paint profiling |
| 98 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 99 | You can use Xephyr to profile how chrome repaints the screen. Xephyr is a |
| 100 | virtual X server like Xnest with debugging options which draws red rectangles to |
| 101 | where applications are drawing before drawing the actual information. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 102 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 103 | export XEPHYR_PAUSE=10000 |
| 104 | Xephyr :1 -ac -screen 800x600 & |
| 105 | DISPLAY=:1 out/Debug/chrome |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 106 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 107 | When ready to start debugging issue the following command, which will tell |
| 108 | Xephyr to start drawing red rectangles: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 109 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 110 | kill -USR1 `pidof Xephyr` |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 111 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 112 | For further information, please refer to |
| 113 | http://cgit.freedesktop.org/xorg/xserver/tree/hw/kdrive/ephyr/README. |