feature request: config option debugging tools #16

Open
opened 2026-03-18 10:01:59 +00:00 by bennolossin · 5 comments

I maintain the pin-init-next tree of the kernel. Every release, I check if my testing configs are up to date, as I want to compile-test all Rust code in the kernel. For this purpose, I'm currently using make menuconfig and then use its search functionality: pressing / and then typing RUST to find all the options that mention RUST (which is hopefully good enough to find most Rust code).

This time, I again encountered a pretty annoying issue:

  • A new driver PWM_TH1520 got added that uses Rust.
  • Checking its entry in menuconfig, I see that the driver cannot be enabled on my hardware. However, I still can compile-test it by enabling COMPILE_TEST.
  • After enabling COMPILE_TEST, my test script encountered the error that CONFIG_RUST is not enabled.
  • Now the painful part of figuring out which part in the huge depends on expression of RUST is not enabled begins. makeconfig is a bit frustrating to work with in this regard:
    • it prints the entire expression on a single line and scrolling is very slow,
    • config options have their value printed (sometimes?) via [=y] or [=n], when they are negated, so !OPTION [=y], I cannot remember the precedence of the [=?] (I only use this feature once a release after all).
    • expressions are printed with no parenthesis for helping with precedence, so a || b && c (which is a problem because I keep forgetting the precedence :)
  • After copying out the depends on expression and analysing it by hand, I found the problem to be RANDSTRUCT.

@kloenk repeatedly told me about this Kconfig parser that she is working on, so when I asked about this feature, she directed me here to add a feature request :)

Ideally, I would have a CLI that I can query for several pieces of information contained in my .config:

  • "print the depends on expression in a readable form for OPTION" including the information of which subexpressions are false and ultimately lead to the option not being available
  • "print all options that transtitively depend on OPTION" also with the addition of "that aren't enabled" to simplify the search for things that use Rust.

The first part is most likely much simpler than the second and would already avoid a lot of the pain. The second one would make my work each release very easy.

I maintain the `pin-init-next` tree of the kernel. Every release, I check if my testing configs are up to date, as I want to compile-test all Rust code in the kernel. For this purpose, I'm currently using `make menuconfig` and then use its search functionality: pressing `/` and then typing `RUST` to find all the options that mention `RUST` (which is hopefully good enough to find most Rust code). This time, I again encountered a pretty annoying issue: - A new driver `PWM_TH1520` got added that uses Rust. - Checking its entry in `menuconfig`, I see that the driver cannot be enabled on my hardware. However, I still can compile-test it by enabling `COMPILE_TEST`. - After enabling `COMPILE_TEST`, my test script encountered the error that `CONFIG_RUST` is not enabled. - Now the painful part of figuring out which part in the huge `depends on` expression of `RUST` is not enabled begins. `makeconfig` is a bit frustrating to work with in this regard: - it prints the entire expression on a single line and scrolling is very slow, - config options have their value printed (sometimes?) via `[=y]` or `[=n]`, when they are negated, so `!OPTION [=y]`, I cannot remember the precedence of the `[=?]` (I only use this feature once a release after all). - expressions are printed with no parenthesis for helping with precedence, so `a || b && c` (which is a problem because I keep forgetting the precedence :) - After copying out the depends on expression and analysing it by hand, I found the problem to be `RANDSTRUCT`. @kloenk repeatedly told me about this Kconfig parser that she is working on, so when I asked about this feature, she directed me here to add a feature request :) Ideally, I would have a CLI that I can query for several pieces of information contained in my `.config`: - "print the `depends on` expression in a readable form for `OPTION`" including the information of which subexpressions are `false` and ultimately lead to the option not being available - "print all options that transtitively depend on `OPTION`" also with the addition of "that aren't enabled" to simplify the search for things that use Rust. The first part is most likely much simpler than the second and would already avoid a lot of the pain. The second one would make my work each release very easy.
Owner

https://cl.afnix.fr/c/rokc/rokc/+/636 implements a initial dependency graph. still planned but missing:

  • De-duplication of recursion of dependent symbols
  • Showing of e.g. prompt dependencies (so only what is needed to show a symbol, not if it can be enabled)
https://cl.afnix.fr/c/rokc/rokc/+/636 implements a initial dependency graph. still planned but missing: - De-duplication of recursion of dependent symbols - Showing of e.g. prompt dependencies (so only what is needed to show a symbol, not if it can be enabled)
Owner

@bennolossin could you split of the reverse dependency feature request into a new issue, so that we can close this issue later and have the revers dependency still open?

@bennolossin could you split of the reverse dependency feature request into a new issue, so that we can close this issue later and have the revers dependency still open?
Author

@kloenk wrote in #16 (comment):

https://cl.afnix.fr/c/rokc/rokc/+/636 implements a initial dependency graph. still planned but missing:

* De-duplication of recursion of dependent symbols

* Showing of e.g. prompt dependencies (so only what is needed to show a symbol, not if it can be enabled)

Thanks a lot for the quick impl! I tested it on my kernel tree and found it to be very useful indeed (it required a bit of hacking to get working). The only thing that I'm missing is the ability to limit the depth of the dependency expression. So only print the direct dependents of RUST and no transtitive ones, or print all transtitive dependencies up to a depth of X.

Here is an example of how it looks like (only a part of the RUST tree):

RUST (y config) [init/Kconfig:2170:1]
├─ HAVE_RUST (y config) [arch/Kconfig:428:1]
├─ RUST_IS_AVAILABLE (y config) [init/Kconfig:70:1]
├─ ! MODVERSIONS || GENDWARFKSYMS (y) [init/Kconfig:2175:13]
│  ├─ ! MODVERSIONS (y) [init/Kconfig:2175:13]
│  │  ├─ MODULES (n default) [kernel/module/Kconfig:1:0]
│  │  └─ ! COMPILE_TEST (n) [kernel/module/Kconfig:163:13]
│  │     └─ HAS_IOMEM (y config) [lib/Kconfig:372:1]
│  │        └─ ! NO_IOMEM (y) [lib/Kconfig:374:13]
│  └─ GENDWARFKSYMS (n) [init/Kconfig:2175:29]
│     ├─ MODVERSIONS (n default) [kernel/module/Kconfig:161:1]
│     │  └─ ! COMPILE_TEST (n) [kernel/module/Kconfig:163:13]
│     ├─ DEBUG_INFO (n default) [lib/Kconfig.debug:249:1]
│     ├─ ! DEBUG_INFO_REDUCED && ! DEBUG_INFO_SPLIT (y) [kernel/module/Kconfig:193:13]
│     │  ├─ ! DEBUG_INFO_REDUCED (y) [kernel/module/Kconfig:193:13]
│     │  └─ ! DEBUG_INFO_SPLIT (y) [kernel/module/Kconfig:193:35]
│     │     └─ ! RISCV || GCC_VERSION >= 120000 (y) [lib/Kconfig.debug:385:13]
│     │        ├─ ! RISCV (y) [lib/Kconfig.debug:385:13]
│     │        └─ GCC_VERSION >= 120000 (n) [lib/Kconfig.debug:385:22]
│     │           └─ GCC_VERSION (0 config) [init/Kconfig:22:1]
│     ├─ ! LTO (y) [kernel/module/Kconfig:195:13]
│     └─ ! X86 || ! DEBUG_INFO_BTF || PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:13]
│        ├─ ! X86 (n) [kernel/module/Kconfig:200:13]
│        └─ ! DEBUG_INFO_BTF || PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:20]
│           ├─ ! DEBUG_INFO_BTF (y) [kernel/module/Kconfig:200:20]
│           │  ├─ ! DEBUG_INFO_SPLIT && ! DEBUG_INFO_REDUCED (y) [lib/Kconfig.debug:400:13]
│           │  │  ├─ ! DEBUG_INFO_SPLIT (y) [lib/Kconfig.debug:400:13]
│           │  │  │  └─ ! RISCV || GCC_VERSION >= 120000 (y) [lib/Kconfig.debug:385:13]
│           │  │  │     ├─ ! RISCV (y) [lib/Kconfig.debug:385:13]
│           │  │  │     └─ GCC_VERSION >= 120000 (n) [lib/Kconfig.debug:385:22]
│           │  │  │        └─ GCC_VERSION (0 config) [init/Kconfig:22:1]
│           │  │  └─ ! DEBUG_INFO_REDUCED (y) [lib/Kconfig.debug:400:33]
│           │  ├─ ! GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST (y) [lib/Kconfig.debug:401:13]
│           │  │  ├─ ! GCC_PLUGIN_RANDSTRUCT (y) [lib/Kconfig.debug:401:13]
│           │  │  └─ COMPILE_TEST (y) [lib/Kconfig.debug:401:39]
│           │  ├─ BPF_SYSCALL (n default) [kernel/bpf/Kconfig:27:1]
│           │  ├─ PAHOLE_VERSION >= 122 (n) [lib/Kconfig.debug:403:13]
│           │  │  └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1]
│           │  └─ ! HEXAGON (y) [lib/Kconfig.debug:405:13]
│           └─ PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:39]
│              ├─ PAHOLE_VERSION < 128 (y) [kernel/module/Kconfig:200:39]
│              │  └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1]
│              └─ PAHOLE_VERSION > 129 (n) [kernel/module/Kconfig:200:63]
│                 └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1]

With only direct dependents, it would look like this instead:

RUST (y config) [init/Kconfig:2170:1]
├─ HAVE_RUST (y config) [arch/Kconfig:428:1]
├─ RUST_IS_AVAILABLE (y config) [init/Kconfig:70:1]
├─ ! MODVERSIONS || GENDWARFKSYMS (y) [init/Kconfig:2175:13]
│  ├─ ! MODVERSIONS (y) [init/Kconfig:2175:13]
│  └─ GENDWARFKSYMS (n) [init/Kconfig:2175:29]
@kloenk wrote in https://git.afnix.fr/rokc/rokc/issues/16#issuecomment-7863: > https://cl.afnix.fr/c/rokc/rokc/+/636 implements a initial dependency graph. still planned but missing: > > * De-duplication of recursion of dependent symbols > > * Showing of e.g. prompt dependencies (so only what is needed to show a symbol, not if it can be enabled) Thanks a lot for the quick impl! I tested it on my kernel tree and found it to be very useful indeed (it required a bit of hacking to get working). The only thing that I'm missing is the ability to limit the depth of the dependency expression. So only print the direct dependents of `RUST` and no transtitive ones, or print all transtitive dependencies up to a depth of `X`. Here is an example of how it looks like (only a part of the RUST tree): ```text RUST (y config) [init/Kconfig:2170:1] ├─ HAVE_RUST (y config) [arch/Kconfig:428:1] ├─ RUST_IS_AVAILABLE (y config) [init/Kconfig:70:1] ├─ ! MODVERSIONS || GENDWARFKSYMS (y) [init/Kconfig:2175:13] │ ├─ ! MODVERSIONS (y) [init/Kconfig:2175:13] │ │ ├─ MODULES (n default) [kernel/module/Kconfig:1:0] │ │ └─ ! COMPILE_TEST (n) [kernel/module/Kconfig:163:13] │ │ └─ HAS_IOMEM (y config) [lib/Kconfig:372:1] │ │ └─ ! NO_IOMEM (y) [lib/Kconfig:374:13] │ └─ GENDWARFKSYMS (n) [init/Kconfig:2175:29] │ ├─ MODVERSIONS (n default) [kernel/module/Kconfig:161:1] │ │ └─ ! COMPILE_TEST (n) [kernel/module/Kconfig:163:13] │ ├─ DEBUG_INFO (n default) [lib/Kconfig.debug:249:1] │ ├─ ! DEBUG_INFO_REDUCED && ! DEBUG_INFO_SPLIT (y) [kernel/module/Kconfig:193:13] │ │ ├─ ! DEBUG_INFO_REDUCED (y) [kernel/module/Kconfig:193:13] │ │ └─ ! DEBUG_INFO_SPLIT (y) [kernel/module/Kconfig:193:35] │ │ └─ ! RISCV || GCC_VERSION >= 120000 (y) [lib/Kconfig.debug:385:13] │ │ ├─ ! RISCV (y) [lib/Kconfig.debug:385:13] │ │ └─ GCC_VERSION >= 120000 (n) [lib/Kconfig.debug:385:22] │ │ └─ GCC_VERSION (0 config) [init/Kconfig:22:1] │ ├─ ! LTO (y) [kernel/module/Kconfig:195:13] │ └─ ! X86 || ! DEBUG_INFO_BTF || PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:13] │ ├─ ! X86 (n) [kernel/module/Kconfig:200:13] │ └─ ! DEBUG_INFO_BTF || PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:20] │ ├─ ! DEBUG_INFO_BTF (y) [kernel/module/Kconfig:200:20] │ │ ├─ ! DEBUG_INFO_SPLIT && ! DEBUG_INFO_REDUCED (y) [lib/Kconfig.debug:400:13] │ │ │ ├─ ! DEBUG_INFO_SPLIT (y) [lib/Kconfig.debug:400:13] │ │ │ │ └─ ! RISCV || GCC_VERSION >= 120000 (y) [lib/Kconfig.debug:385:13] │ │ │ │ ├─ ! RISCV (y) [lib/Kconfig.debug:385:13] │ │ │ │ └─ GCC_VERSION >= 120000 (n) [lib/Kconfig.debug:385:22] │ │ │ │ └─ GCC_VERSION (0 config) [init/Kconfig:22:1] │ │ │ └─ ! DEBUG_INFO_REDUCED (y) [lib/Kconfig.debug:400:33] │ │ ├─ ! GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST (y) [lib/Kconfig.debug:401:13] │ │ │ ├─ ! GCC_PLUGIN_RANDSTRUCT (y) [lib/Kconfig.debug:401:13] │ │ │ └─ COMPILE_TEST (y) [lib/Kconfig.debug:401:39] │ │ ├─ BPF_SYSCALL (n default) [kernel/bpf/Kconfig:27:1] │ │ ├─ PAHOLE_VERSION >= 122 (n) [lib/Kconfig.debug:403:13] │ │ │ └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1] │ │ └─ ! HEXAGON (y) [lib/Kconfig.debug:405:13] │ └─ PAHOLE_VERSION < 128 || PAHOLE_VERSION > 129 (y) [kernel/module/Kconfig:200:39] │ ├─ PAHOLE_VERSION < 128 (y) [kernel/module/Kconfig:200:39] │ │ └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1] │ └─ PAHOLE_VERSION > 129 (n) [kernel/module/Kconfig:200:63] │ └─ PAHOLE_VERSION (0 config) [init/Kconfig:184:1] ``` With only direct dependents, it would look like this instead: ```text RUST (y config) [init/Kconfig:2170:1] ├─ HAVE_RUST (y config) [arch/Kconfig:428:1] ├─ RUST_IS_AVAILABLE (y config) [init/Kconfig:70:1] ├─ ! MODVERSIONS || GENDWARFKSYMS (y) [init/Kconfig:2175:13] │ ├─ ! MODVERSIONS (y) [init/Kconfig:2175:13] │ └─ GENDWARFKSYMS (n) [init/Kconfig:2175:29] ```
Author

@kloenk wrote in #16 (comment):

@bennolossin could you split of the reverse dependency feature request into a new issue, so that we can close this issue later and have the revers dependency still open?

Done, created #17.

@kloenk wrote in https://git.afnix.fr/rokc/rokc/issues/16#issuecomment-7864: > @bennolossin could you split of the reverse dependency feature request into a new issue, so that we can close this issue later and have the revers dependency still open? Done, created #17.
Author

I tried the new versions a couple of days ago and the depth parameter is exactly what I need. I have a couple of improvement ideas:

  • color code (y) and (n) to make it easier to find the disabled option
  • when printing negations, there shouldn't be a space between ! and the expression, so !VALUE or !(V1 && V2)

Thanks a lot for this!

I tried the new versions a couple of days ago and the depth parameter is exactly what I need. I have a couple of improvement ideas: - color code `(y)` and `(n)` to make it easier to find the disabled option - when printing negations, there shouldn't be a space between `!` and the expression, so `!VALUE` or `!(V1 && V2)` Thanks a lot for this!
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rokc/rokc#16
No description provided.