summaryrefslogtreecommitdiff
path: root/kleaf/docs/debugging.md
blob: bf2bfd3a01772b63b858383070cd6e8a1dab01fc (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
# Debugging Kleaf

## Debugging Options

This is a non exhaustive list of options to help debugging compilation issues:

*   Customise Kleaf:

    *   `--debug_annotate_scripts`: Runs all script invocations with `set -x`
        and a trap that executes `date` after every command.

    *   `--debug_print_scripts`: Prints the content of the (generated) command
        scripts during rule execution.

    *   `--debug_cache_dir_conflict={detect,resolve}`: Attempt to detect or
        resolve any conflicts if multiple actions uses the same subdirectory
        within `--cache_dir` simultaneously.

*   Customise Kbuild:

    *   `--debug_make_verbosity`: Controls verbosity of `make` executions.
        *   `E` (default): Only print errors (`make -s`)
        *   `I`: print brief description of make targets being built (`make`)
        *   `D`: print full commands (`make V=1`)
        *   `V`: print the reason for the rebuild of each make target
            (`make V=2`)

    *   `--debug_modpost_warn`: Sets
        [`KBUILD_MODPOST_WARN=1`](https://www.kernel.org/doc/html/latest/kbuild/kbuild.html#kbuild-modpost-warn).
        TL; DR. can be set to avoid errors in case of undefined symbols in the
        final module linking stage. It changes such errors into warnings.

*   Customise Bazel:

    *   `--sandbox_debug`: Enables debugging features for the
        [sandboxing feature](https://bazel.build/docs/sandboxing).
    *   `--verbose_failures`: If a command fails, print out the full command
        line.
    *   `--jobs`: This option, which takes an integer argument, specifies a
        limit on the number of jobs that should be executed concurrently during
        the execution phase of the build.
    *   For a complete list see https://bazel.build/docs/user-manual

## Disabling checks

This is a list of options to disable checks in Kleaf due to various reasons. For
example, some checks may be disabled during device bring-up for a quick
development cycle. Usually, these flags should not be set on a release build.

*   `--allow_ddk_unsafe_headers`: Allow DDK modules to also use the unsafe
    header list in the common package.
*   `--allow_undeclared_modules`: Allow modules to be undeclared in
    `kernel_build.module_outs` and `kernel_build.module_implicit_outs`. If
    modules are built but not declared in these lists, Kleaf emits a warning
    unless `--nowarn_undeclared_modules` is set.
*   `--nowarn_undeclared_modules`: Allow modules to be undeclared in
    `kernel_build.module_outs` and `kernel_build.module_implicit_outs`. No
    warnings are generated.
*   `--nokmi_symbol_list_strict_mode`: Disable KMI symbol list check.
*   `--nokmi_symbol_list_violations_check`: Disable KMI symbol list violations
    check.

## Debugging incremental build issues

Incremental build issues refers to issues where actions are executed in an
incremental build, but you do not expect them to be executed, or the reverse.

For example, if you are debugging why
`//common-modules/virtual-device:x86_64/goldfish_drivers/goldfish_pipe` is
rebuilt after you change a core kernel file, you may execute the following:

```shell
# Custom flags provided to the build; change accordingly
$ FLAGS="--config=fast"

# Build
$ tools/bazel build "${FLAGS}" //common-modules/virtual-device:x86_64/goldfish_drivers/goldfish_pipe

# Record hashes of all input files to the action
# Note that kernel_module() defines multiple actions, so use mnemonic() to filter out
# the non-interesting ones.
$ build/kernel/kleaf/analysis/inputs.py -- "${FLAGS}" \
  'mnemonic(KernelModule, //common-modules/virtual-device:x86_64/goldfish_drivers/goldfish_pipe)' \
  > out/hash_1.txt

# Change a core kernel file, e.g.
$ echo >> common/kernel/sched/core.c

# Build again
$ tools/bazel build "${FLAGS}" //common-modules/virtual-device:x86_64/goldfish_drivers/goldfish_pipe

# Record hashes of all input files to the action
$ build/kernel/kleaf/analysis/inputs.py -- "${FLAGS}" \
  'mnemonic(KernelModule, //common-modules/virtual-device:x86_64/goldfish_drivers/goldfish_pipe)' \
  > out/hash_2.txt

# Compare hashes, e.g.
$ diff out/hash_1.txt out/hash_2.txt
```

Positional arguments to `build/kernel/kleaf/analysis/inputs.py` are fed directly
to `tools/bazel aquery`. Visit
[Action Graph Query](https://bazel.build/query/aquery) for the query language.

## Debugging dependencies on external repositories

If you see an error like this:

```
ERROR: An error occurred during the fetch of repository 'rules_python':
   Traceback (most recent call last):
        File "<...>/http.bzl", line 132, column 45, in _http_archive_impl
                download_info = ctx.download_and_extract(
[...]
ERROR: <...>:24:22: While resolving toolchains for target <...>: invalid registered toolchain '@bazel_tools//tools/jdk:all': while parsing '@bazel_tools//tools/jdk:all': no such package '@rules_python//python': java.io.IOException: Error downloading <...>
```

In this example, the error message suggests that `@bazel_tools//tools/jdk:all`
has a dependency on `@rules_python`.

If this error is unexpected, you may try these commands to diagnose issues with
external repositories:

```sh
rm -rf /tmp/temp_repo_cache && mkdir -p /tmp/temp_repo_cache
bazel clean --expunge
bazel query @bazel_tools//tools/jdk:all \
  --repository_cache=/tmp/temp_repo_cache \
  --experimental_repository_disable_download
```

## Debugging target `providers`

Inspecting the information exposed by bazel targets via
[providers](https://bazel.build/extending/rules#providers) is possible following
[Defining the output format using Starlark](https://bazel.build/query/cquery#output-format-definition)
docs.

Here is an example used in
[CL:2615849](https://android-review.googlesource.com/c/kernel/build/+/2615849)
to inspect the information exposed by `KernelBuildAbiInfo` from
`//common:kernel_aarch64_download_or_build` target.

```sh
$ tools/bazel cquery //common:kernel_aarch64_download_or_build --use_prebuilt_gki=10283028  --output=starlark --starlark:expr='providers(target)["//build/kernel/kleaf/impl:common_providers.bzl%KernelBuildAbiInfo"]'

...
struct(module_outs_file = <source file file/kernel_aarch64_modules>, modules_staging_archive = <source file file/modules_staging_dir.tar.gz>, src_protected_modules_list = <source file file/gki_aarch64_protected_modules>)
...

```

## Reproducing sandboxed commands

Sometimes you need to reproduce commands that was exectuted in hermetic sandbox
environment, for example, to catch a bug in compiler. Then you may follow these
approximate steps:

1. Run `tools/bazel build --debug_make_verbosity=D --debug_print_scripts
   --sandbox_debug //common:kernel_aarch64`. These options will print out all
   executed commands and preserve sandbox environment.
2. Run `find out -name 'command.log'` and open log in your favorite text editor.
   This log have the same contents as stdout and stderr of Bazel invocation.
3. Find in log for example `drivers/net/usb/usbnet.o` to get corresponding
   compiler invocation.
4. Search *up* for `Run this command to start an interactive shell in an
   identical sandboxed environment`. There may be multiple sandboxed
   environments, you need to find the closest one before the interesting
   command.
5. Search *down* from here for `+ export PATH=`. Plus sign is important, it will
   show an actual path to hermetic toolchain with expanded variables.
6. Run commands from step 4 to get into sandboxed environment, then from step 5
   to have toolchain binaries in your path, and then from step 3 to reproduce
   compiler invocation.