blob: d58e44f823f30430144a0008e60418c6d144800c [file] [log] [blame] [view]
Andrew Grieve860b1552017-09-06 14:50:061# Static Initializers
2
3[TOC]
4
5Some background on the original decision to ban static initializers:
6
7http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html
8
Andrew Grieve5e704682021-02-19 23:35:249Note: Another name for static initializers is "global constructors".
10
Andrew Grieve860b1552017-09-06 14:50:0611# How Static Initializers are Checked
12
Arthur Milchior7b39ba22024-11-14 14:32:5713* For Linux, Mac and iOS:
Matthew Denton43cafd52021-05-26 15:42:1414 * The expected count is stored in [//testing/scripts/check_static_initializers.py](https://source.chromium.org/chromium/chromium/src/+/main:testing/scripts/check_static_initializers.py)
Andrew Grieve860b1552017-09-06 14:50:0615* For Android:
David Benjamin17fce3e8b2022-08-04 19:43:0316 * The expected count is stored in [//chrome/android/static_initializers.gni](https://cs.chromium.org/chromium/src/chrome/android/static_initializers.gni)
Andrew Grieve860b1552017-09-06 14:50:0617
18## Removing Static Initializers
19
20Common fixes include:
21
Lei Zhangfafa2b72020-09-29 21:58:4622* Add constexpr.
23* Move global variable to be a static variable within a function that returns
24 it, often wrapped in `base::NoDestructor`.
Andrew Grieve860b1552017-09-06 14:50:0625
26## Listing Static Initializers
27
Andrew Grieve5d0ac9cf2022-10-14 01:12:0028### Option 1 - dump-static-initializers.py
Andrew Grieve860b1552017-09-06 14:50:0629For Linux:
30
31 tools/linux/dump-static-initializers.py out/Release/chrome
32
Andrew Grieve5d0ac9cf2022-10-14 01:12:0033For Android:
Andrew Grieve860b1552017-09-06 14:50:0634
Andrew Grieve3c2c4202020-04-16 01:55:0535 # Build with: is_official_build=true is_chrome_branded=true
36 # This will dump the list of SI's only when they don't match the expected
37 # number in static_initializers.gni (this is what the bots use).
Mohamed Heikaldbeb5222024-01-15 22:28:0138 ninja chrome/android:check_chrome_static_initializers
Andrew Grieve5d0ac9cf2022-10-14 01:12:0039 # or, to dump directly:
40 tools/linux/dump-static-initializers.py out/Release/lib.unstripped/libmonochrome.so
Andrew Grieve5e704682021-02-19 23:35:2441
Andrew Grieve5d0ac9cf2022-10-14 01:12:0042### Option 2 - Ask compiler to report them
Andrew Grieve5e704682021-02-19 23:35:2443
Adenilson Cavalcanti9b156832021-10-27 00:50:1444If the source of the new initializers is not obvious from Step 1, you can ask the
Andrew Grieve5e704682021-02-19 23:35:2445compiler to pinpoint the exact source line.
46
471. Edit [//build/config/BUILDCONFIG.gn](https://cs.chromium.org/chromium/src/build/config/BUILDCONFIG.gn)
48and add `"//build/config/compiler:wglobal_constructors"` to `default_compiler_configs`
492. Remove the config from the `configs` in `//base:base`
503. Set GN arg `treat_warnings_as_errors=false`
514. Compile and look for warnings **from the files identified by step 1** (may want to pipe ninja output to a file).
52
53*** note
54The compiler warning triggers for every static initializer that exists
55*before optimization*. We care only about those that survive optimization.
56More details in [crbug/1136086](https://bugs.chromium.org/p/chromium/issues/detail?id=1136086).
57***
Andrew Grieve860b1552017-09-06 14:50:0658
Andrew Grieve3c2c4202020-04-16 01:55:0559* For more information about `diagnose_bloat.py`, refer to its [README.md](/tools/binary_size/README.md#diagnose_bloat.py)
60* List of existing static initializers documented in [static_initializers.gni](/chrome/android/static_initializers.gni)
Adenilson Cavalcanti9b156832021-10-27 00:50:1461
Andrew Grieve5d0ac9cf2022-10-14 01:12:0062### Option 3 - Manual Verification
Adenilson Cavalcanti9b156832021-10-27 00:50:1463
Andrew Grieve5d0ac9cf2022-10-14 01:12:0064You can manually go through the steps that `dump-static-initializers.py` does.
Adenilson Cavalcanti9b156832021-10-27 00:50:1465
Andrew Grieve7c58e2e2022-04-22 02:00:10661. Locate the address range of the .init_array section with:
Adenilson Cavalcanti9b156832021-10-27 00:50:1467```
Andrew Grieve7c58e2e2022-04-22 02:00:1068$ third_party/llvm-build/Release+Asserts/bin/llvm-readelf \
69 --hex-dump=.init_array out/Release/lib.unstripped/libmonochrome.so
70Hex dump of section '.init_array':
710x04064624 294a1a02 154acb00 79d3be01 894c1a02 )J...J..y....L..
Adenilson Cavalcanti9b156832021-10-27 00:50:1472```
Andrew Grieve7c58e2e2022-04-22 02:00:1073
74* `0x04064624` is the location of `.init_array`.
75* The other four entries are addresses of functions **in little endian**.
76
772. Convert the address into a function name with:
78
Adenilson Cavalcanti9b156832021-10-27 00:50:1479```
Andrew Grieve7c58e2e2022-04-22 02:00:1080# Reverse hex pairs to account for endianness.
81$ third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer \
82 --functions -e out/Release/lib.unstripped/libmonochrome.so 0x021a4a29
83_GLOBAL__I_000101
84./../../buildtools/third_party/libc++/trunk/src/iostream.cpp:0:0
85```
86
873. If any `.init_array` slots are zero, that means they their address is exists
88within the relocation table. To find the address:
89
90```
91# Use the location of ".init_array" printed in step 1, plus an offset for subsequent slots.
92$ third_party/llvm-build/Release+Asserts/bin/llvm-readelf \
93 --relocations out/Release/lib.unstripped/libmonochrome.so | grep 0x04064624
9403dfb7b0 00000017 R_ARM_RELATIVE 0
95```