aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/README.md
blob: 8d0ff58cbb7a645fa192a7f488cd60c21dc2ebc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# LLVM Tools

## Overview

These scripts helps automate tasks such as updating the LLVM next hash,
determing whether a new patch applies correctly, and patch management.

In addition, there are scripts that automate the process of retrieving the
git hash of LLVM from either google3, top of trunk, or for a specific SVN
version.

**NOTE: All scripts must must be run outside the chroot**

**NOTE: sudo must be permissive (i.e. **`cros_sdk`** should NOT prompt for a
password)**

## `update_packages_and_run_tests.py`

### Usage

This script is used for updating a package's LLVM hash (sys-devel/llvm,
sys-libs/compiler-rt, sys-libs/libcxx, and sys-libs/llvm-libunwind)
and then run tests after updating the git hash. There are three ways to test
the change, including starting tryjobs, recipe builders or using cq+1.

An example when this script should be run is when certain boards would like
to be tested with the updated `LLVM_NEXT_HASH`.

For example:

```
$ ./update_packages_and_run_tests.py \
  --is_llvm_next \
  --llvm_version tot \
  tryjobs \
  --options nochromesdk latest-toolchain \
  --builders kevin-release-tryjob nocturne-release-tryjob
```

The above example would update the packages' `LLVM_NEXT_HASH` to the top of
trunk's git hash and would submit tryjobs for kevin and nocturne boards, passing
in 'nochromesdk' and 'latest-toolchain' for each tryjob.

For help with the command line arguments of the script, run:

```
$ ./update_packages_and_run_tests.py --help
```

Similarly as the previous example, but for updating `LLVM_HASH` to
google3 and test with cq+1:

```
$ ./update_packages_and_run_tests.py \
  --llvm_version google3 \
  cq
```

Similarly as the previous example, but for updating `LLVM_NEXT_HASH` to
the git hash of revision 367622 and test with recipe builders:

```
$ ./update_packages_and_run_tests.py \
  --is_llvm_next \
  --llvm_version 367622 \
  recipe \
  --options -nocanary \
  --builders chromeos/toolchain/kevin-llvm chromeos/toolchain/nocturne-llvm
```

## `update_chromeos_llvm_hash.py`

### Usage

This script is used for updating a package's/packages' LLVM hashes and
creating a change list of those changes which will uploaded for review. For
example, some changes that would be included in the change list are
the updated ebuilds, changes made to the patches of the updated packages such
as being removed or an updated patch metadata file. These changes are determined
by the `--failure_mode` option.

An example where this script would be used is when multiple packages need to
have their `LLVM_NEXT_HASH` updated.

For example:

```
$ ./update_chromeos_llvm_hash.py \
  --update_packages sys-devel/llvm sys-libs/compiler-rt \
  --is_llvm_next \
  --llvm_version google3 \
  --failure_mode disable_patches
```

The example above would update sys-devel/llvm and sys-libs/compiler-rt's
`LLVM_NEXT_HASH` to the latest google3's git hash of LLVM. And the change list
may include patches that were disabled for either sys-devel/llvm or
sys-libs/compiler-rt.

For help with the command line arguments of the script, run:

```
$ ./update_chromeos_llvm_hash.py --help
```

For example, to update `LLVM_HASH` to top of trunk of LLVM:

```
$ ./update_chromeos_llvm_hash.py \
  --update_packages sys-devel/llvm sys-libs/compiler-rt \
  --llvm_version tot \
  --failure_mode disable_patches
```

For example, to create a roll CL to the git hash of revision 367622:

```
$ ./update_chromeos_llvm_hash.py \
  --update_packages sys-devel/llvm sys-libs/compiler-rt \
  sys-libs/libcxx sys-libs/llvm-libunwind \
  'dev-util/lldb-server' \
  --llvm_version 367622 \
  --failure_mode disable_patches
```

## `patch_manager.py`

### Usage

This script is used when when all the command line arguments are known such as
testing a specific metadata file or a specific source tree.

For help with the command line arguments of the script, run:

```
$ ./patch_manager.py --help
```

For example, to see all the failed (if any) patches:

```
$ ./patch_manager.py \
  --svn_version 367622 \
  --patch_metadata_file /abs/path/to/patch/file \
  --src_path /abs/path/to/src/tree \
  --failure_mode continue
```

For example, to disable all patches that failed to apply:

```
$ ./patch_manager.py \
  --svn_version 367622 \
  --patch_metadata_file /abs/path/to/patch/file \
  --src_path /abs/path/to/src/tree \
  --failure_mode disable_patches
```

For example, to remove all patches that no longer apply:

```
$ ./patch_manager.py \
  --svn_version 367622 \
  --patch_metadata_file /abs/path/to/patch/file \
  --src_path /abs/path/to/src/tree \
  --failure_mode remove_patches
```

For example, to bisect a failing patch and stop at the first bisected patch:

```
$ ./patch_manager.py \
  --svn_version 367622 \
  --patch_metadata_file /abs/path/to/patch/file \
  --src_path /abs/path/to/src/tree \
  --failure_mode bisect_patches \
  --good_svn_version 365631
```

For example, to bisect a failing patch and then continue bisecting the rest of
the failed patches:

```
$ ./patch_manager.py \
  --svn_version 367622 \
  --patch_metadata_file /abs/path/to/patch/file \
  --src_path /abs/path/to/src/tree \
  --failure_mode bisect_patches \
  --good_svn_version 365631 \
  --continue_bisection True
```

## LLVM Bisection

### `llvm_bisection.py`

#### Usage

This script is used to bisect a bad revision of LLVM. After the script finishes,
the user requires to run the script again to continue the bisection. Intially,
the script creates a JSON file that does not exist which then continues
bisection (after invoking the script again) based off of the JSON file.

For example, assuming the revision 369420 is the bad revision:

```
$ ./llvm_bisection.py \
  --parallel 3 \
  --start_rev 369410 \
  --end_rev 369420 \
  --last_tested /abs/path/to/tryjob/file/ \
  --extra_change_lists 513590 \
  --builder eve-release-tryjob \
  --options latest-toolchain
```

The above example bisects the bad revision (369420), starting from the good
revision 369410 and launching 3 tryjobs in between if possible (`--parallel`).
Here, the `--last_tested` path is a path to a JSON file that does not exist. The
tryjobs are tested on the eve board. `--extra_change_lists` and `--options`
indicate what parameters to pass into launching a tryjob.

For help with the command line arguments of the script, run:

```
$ ./llvm_bisection.py --help
```

### `auto_llvm_bisection.py`

#### Usage

This script automates the LLVM bisection process by using `cros buildresult` to
update the status of each tryjob.

An example when this script would be used to do LLVM bisection overnight
because tryjobs take very long to finish.

For example, assuming the good revision is 369410 and the bad revision is
369420, then:

```
$ ./auto_llvm_bisection.py --start_rev 369410 --end_rev 369420 \
  --last_tested /abs/path/to/last_tested_file.json \
  --extra_change_lists 513590 1394249 \
  --options latest-toolchain nochromesdk \
  --chroot_path /path/to/chromeos/chroot \
  --builder eve-release-tryjob
```

The example above bisects LLVM between revision 369410 and 369420. If the file
exists, the script resumes bisection. Otherwise, the script creates the file
provided by `--last_tested`. `--extra_change_lists` and `--options` are used for
each tryjob when being submitted. Lastly, the tryjobs are launched for the board
provided by `--builder` (in this example, for the eve board).

For help with the command line arguments of the script, run:

```
$ ./auto_llvm_bisection.py --help
```

### `update_tryjob_status.py`

#### Usage

This script updates a tryjob's 'status' value when bisecting LLVM. This script
can use the file that was created by `llvm_bisection.py`.

An example when this script would be used is when the result of tryjob that was
launched was 'fail' (due to flaky infra) but it should really have been
'success'.

For example, to update a tryjob's 'status' to 'good':

```
$ ./update_tryjob_status.py \
  --set_status good \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file
```

The above example uses the file in `--status_file` to update a tryjob in that
file that tested the revision 369412 and sets its 'status' value to 'good'.

For help with the command line arguments of the script, run:

```
$ ./update_tryjob_status.py --help
```

For example, to update a tryjob's 'status' to 'bad':

```
$ ./update_tryjob_status.py \
  --set_status bad \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file
```

For example, to update a tryjob's 'status' to 'pending':

```
$ ./update_tryjob_status.py \
  --set_status pending \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file
```

For example, to update a tryjob's 'status' to 'skip':

```
$ ./update_tryjob_status.py \
  --set_status skip \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file
```

For example, to update a tryjob's 'status' based off a custom script exit code:

```
$ ./update_tryjob_status.py \
  --set_status custom_script \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file \
  --custom_script /abs/path/to/script.py
```

### `modify_a_tryjob.py`

#### Usage

This script modifies a tryjob directly given an already created tryjob file when
bisecting LLVM. The file created by `llvm_bisection.py` can be used in this
script.

An example when this script would be used is when a tryjob needs to be manually
added.

For example:

```
$ ./modify_a_tryjob.py \
  --modify_a_tryjob add \
  --revision 369416 \
  --extra_change_lists 513590 \
  --options latest-toolchain \
  --builder eve-release-tryjob \
  --status_file /abs/path/to/tryjob/file
```

The above example creates a tryjob that tests revision 369416 on the eve board,
passing in the extra arguments (`--extra_change_lists` and `--options`). The
tryjob is then inserted into the file passed in via `--status_file`.

For help with the command line arguments of the script, run:

```
$ ./modify_a_tryjob.py --help
```

For example, to remove a tryjob that tested revision 369412:

```
$ ./modify_a_tryjob.py \
  --modify_a_tryjob remove \
  --revision 369412 \
  --status_file /abs/path/to/tryjob/file
```

For example, to relaunch a tryjob that tested revision 369418:

```
$ ./modify_a_tryjob.py \
  --modify_a_tryjob relaunch \
  --revision 369418 \
  --status_file /abs/path/to/tryjob/file
```

## Other Helpful Scripts

### `get_llvm_hash.py`

#### Usage

The script has a class that deals with retrieving either the top of trunk git
hash of LLVM, the git hash of google3, or a specific git hash of a SVN version.
It also has other functions when dealing with a git hash of LLVM.

In addition, it has a function to retrieve the latest google3 LLVM version.

For example, to retrieve the top of trunk git hash of LLVM:

```
from get_llvm_hash import LLVMHash

LLVMHash().GetTopOfTrunkGitHash()
```

For example, to retrieve the git hash of google3:

```
from get_llvm_hash import LLVMHash

LLVMHash().GetGoogle3LLVMHash()
```

For example, to retrieve the git hash of a specific SVN version:

```
from get_llvm_hash import LLVMHash

LLVMHash().GetLLVMHash(<svn_version>)
```

For example, to retrieve the latest google3 LLVM version:

```
from get_llvm_hash import GetGoogle3LLVMVersion

GetGoogle3LLVMVersion(stable=True)
```

### `git_llvm_rev.py`

This script is meant to synthesize LLVM revision numbers, and translate between
these synthesized numbers and git SHAs. Usage should be straightforward:

```
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --rev r380000
6f635f90929da9545dd696071a829a1a42f84b30
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --sha 6f635f90929da9545dd696071a829a1a42f84b30
r380000
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --sha origin/some-branch
r387778
```

**Tip**: if you put a symlink called `git-llvm-rev` to this script somewhere on
your `$PATH`, you can also use it as `git llvm-rev`.

### `get_upstream_patch.py`

#### Usage

This script updates the proper ChromeOS packages with LLVM patches of your choosing, and
copies the patches into patch folders of the packages. This tool supports both git hash
of commits as well as differential reviews.

Usage:

```
./get_upstream_patch.py --chroot_path /abs/path/to/chroot --start_sha llvm
--sha 174c3eb69f19ff2d6a3eeae31d04afe77e62c021 --sha 174c3eb69f19ff2d6a3eeae31d04afe77e62c021
--differential D123456
```

It tries to autodetect a lot of things (e.g., packages changed by each sha,
their ebuild paths, the "start"/"end" revisions to set, etc.) By default the
script creates a local patch. Use --create_cl option to create a CL instead. For
more information, please see the `--help`

### `revert_checker.py`

**This script is copied from upstream LLVM. Please prefer to make upstream edits,
rather than modifying this script. It's kept in a CrOS repo so we don't need an
LLVM tree to `import` this from scripts here.**

This script reports reverts which happen 'across' a certain LLVM commit.

To clarify the meaning of 'across' with an example, if we had the following
commit history (where `a -> b` notes that `b` is a direct child of `a`):

123abc -> 223abc -> 323abc -> 423abc -> 523abc

And where 423abc is a revert of 223abc, this revert is considered to be 'across'
323abc. More generally, a revert A of a parent commit B is considered to be
'across' a commit C if C is a parent of A and B is a parent of C.

Usage example:

```
./revert_checker.py -C llvm-project-copy 123abc 223abc 323abc
```

In the above example, the tool will scan all commits between 123abc and 223abc,
and all commits between 123abc and 323abc for reverts of commits which are
parents of 123abc.

### `nightly_revert_checker.py`

This is an automated wrapper around `revert_checker.py`. It checks to see if any
new reverts happened across toolchains that we're trying to ship since it was
last run. If so, it either automatically cherry-picks the reverts, or sends
emails to appropriate groups.

Usage example for cherry-picking:
```
PYTHONPATH=../ ./nightly_revert_checker.py \
  cherry-pick
  --state_file state.json \
  --llvm_dir llvm-project-copy \
  --chromeos_dir ../../../../
  --reviewers=chromium-os-mage@google.com
```

Usage example for email:
```
PYTHONPATH=../ ./nightly_revert_checker.py \
  email
  --state_file state.json \
  --llvm_dir llvm-project-copy \
  --chromeos_dir ../../../../
```

### `bisect_clang_crashes.py`

This script downloads clang crash diagnoses from
gs://chromeos-toolchain-artifacts/clang-crash-diagnoses and sends them to 4c for
bisection.

Usage example:

```
$ ./bisect_clang_crashes.py --4c 4c-cli --state_file ./output/state.json
```

The above command downloads the artifacts of clang crash diagnoses and send them
to 4c server for bisection. The summary of submitted jobs will be saved in
output/state.json under the current path. The output directory will be created
automatically if it does not exist yet. To get more information of the submitted
jobs, please refer to go/4c-cli.

### `upload_lexan_crashes_to_forcey.py`

This script downloads clang crash diagnoses from Lexan's bucket and sends them
to 4c for bisection.

Usage example:

```
$ ./upload_lexan_crashes_to_forcey.py --4c 4c-cli \
    --state_file ./output/state.json
```

The above command downloads the artifacts of clang crash diagnoses and send them
to 4c server for bisection. The summary of submitted jobs will be saved in
output/state.json under the current path. The output directory will be created
automatically if it does not exist yet. To get more information of the submitted
jobs, please refer to go/4c-cli.

Note that it's recommended to 'seed' the state file with a most recent upload
date. This can be done by running this tool *once* with a `--last_date` flag.
This flag has the script override whatever's in the state file (if anything) and
start submitting all crashes uploaded starting at the given day.

### `werror_logs.py`

This tool exists to help devs reason about `-Werror` instances that _would_
break builds, were the `FORCE_DISABLE_WERROR` support in the compiler wrapper
not enabled.

Usage example:

```
$ ./werror_logs.py aggregate \
    --directory=${repo}/out/sdk/tmp/portage/dev-cpp/gtest-1.13.0-r12/cros-artifacts
```

## `fetch_cq_size_diff.py`

This script should be runnable both inside and outside of the chroot.

This script exists to help users fill in the llvm-next testing matrix. It's
capable of comparing the sizes of ChromeOS images, and the size of Chrome's
debuginfo. An example of this is:

```
$ ./fetch_cq_size_diff.py --image gs \
  gs://chromeos-image-archive/asurada-release/R122-15712.0.0/image.zip
  gs://chromeos-image-archive/asurada-cq/R122-15712.0.0-92036-8761629109681962289/image.zip
```

For convenience, this script can also figure out what to compare from a CL, like
so:

```
$ ./fetch_cq_size_diff.py --image cl \
  https://chromium-review.googlesource.com/c/chromiumos/overlays/board-overlays/+/5126116/3
```

In the above case, this script will find a completed CQ build associated with
PatchSet 3 of the given CL, and compare the `image.zip` generated by said build
with the image.zip generated by a release builder for the same board. CQ
attempts don't have to be entirely green for this; as long as there're a few
green boards to pick from, this script should be able to make a comparison.