dbg: the boot menu can turn on remote debugging, in a debug build
schdbgd ships Disabled, and its manifest explains why: a debugger that can read
the process table should not run on a machine whose owner never asked for one.
That default is right and has one bad consequence -- **the machines that most
need debugging are the ones you cannot get a shell on to enable it.** A laptop
with no serial port that stops before it can draw has nowhere to say why, and
`schinitd enable` needs a prompt that does not exist.
So `make DEBUG=1` adds a sixth entry to the F8 menu. Picking it toggles;
booting carries the choice through SCHBOOT_DEBUG_FLAG; the kernel publishes
/proc/bootdebug; schinitd starts the one job that flag may un-disable, with
the manifest's Args now naming 0.0.0.0 -- a debugger reachable only from the
machine being debugged is no use when that machine is the one that will not
talk to you.
Four decisions, since this is a network-reachable debugger:
compiled out, not hidden A release build cannot set the flag because the
code that would set it is not in the binary. A
menu item that is present and refuses is an
invitation to make it not refuse.
consent at the machine Somebody standing at the keyboard during boot is
the strongest consent this system can ask for and
the weakest one that is any use on hardware that
will not boot.
one job, named in schinitd Not a manifest key like EnableIfDebug: the general
version of "the boot menu starts things that ship
off" is worse than the specific one, and this way
what the flag can start is one readable line.
the kernel only publishes Nothing in the kernel behaves differently, so a
debug kernel and a release kernel are the same
kernel and a bug cannot be the flag's fault.
/proc/bootdebug is its own file rather than a second line in /proc/bootmode,
because bootmode's whole promise is that reading it is a string compare and
not a parser.
**Also: `tone` stopped lying.** On a machine with no sound card it reported
"the device will not take 16-bit samples", which sends you looking at the
format code instead of at the empty PCI slot -- /dev/dsp exists whether or not
hardware is behind it, and the ioctl is where the absence shows up. ENODEV is
now told apart from a format refusal.
Verified end to end: F8 -> item 6 -> boot -> schinitd says it is starting
schdbgd -> a client outside the VM connected to the forwarded port and ran
`dma`, getting the real arena dump back. The release build has no such entry
in the binary at all, and boots clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
9fea18b18b
commit
30a0d0fbed
11 changed files with 204 additions and 20 deletions
|
|
@ -20,6 +20,51 @@ watchpoints.
|
|||
|
||||
---
|
||||
|
||||
## Turning it on at the boot menu
|
||||
|
||||
`schdbgd` ships `Disabled`, and the reason is in its manifest: a debugger that
|
||||
can read the process table should not be running on a machine whose owner never
|
||||
asked for one. That is the right default and it has one bad consequence —
|
||||
**the machines that most need debugging are the ones you cannot get a shell on
|
||||
to enable it.** A laptop with no serial port that stops before it can draw has
|
||||
nowhere to say why, and `schinitd enable` needs a prompt that does not exist.
|
||||
|
||||
So a build made with `make DEBUG=1` has a sixth entry in the F8 menu:
|
||||
|
||||
```
|
||||
> 6. Remote debugging: off
|
||||
```
|
||||
|
||||
Picking it toggles the entry, booting carries the choice through
|
||||
`SCHBOOT_DEBUG_FLAG`, the kernel publishes it as `/proc/bootdebug`, and
|
||||
`schinitd` starts the one job that flag is allowed to un-disable. Plug the
|
||||
machine into a router, pick the entry, and connect from the laptop next to it:
|
||||
|
||||
```sh
|
||||
nc 192.168.1.50 4444
|
||||
dma
|
||||
```
|
||||
|
||||
Four decisions worth stating, because this is a network-reachable debugger:
|
||||
|
||||
**It is compiled out, not hidden.** A release build has no way to set the flag,
|
||||
because the code that would set it is not in the binary. A menu item that is
|
||||
present and refuses is an invitation to work out how to make it not refuse.
|
||||
|
||||
**The consent is asked for at the machine.** Somebody standing at the keyboard
|
||||
during boot is the strongest consent this system can ask for, and the weakest
|
||||
one that is any use on hardware that will not boot.
|
||||
|
||||
**One job, named in `schinitd`.** Not a manifest key like `EnableIfDebug` — the
|
||||
general version of "the boot menu can start things that ship switched off" is a
|
||||
worse idea than the specific one, and this way the list of what the flag can
|
||||
start is one line anybody can read.
|
||||
|
||||
**The kernel does nothing with the flag but publish it.** A kernel that changed
|
||||
behaviour on a debug flag would be a kernel whose bugs could depend on it, and
|
||||
a debug build and a release build would stop being the same kernel.
|
||||
|
||||
|
||||
## The rule the shape follows
|
||||
|
||||
**It observes; it does not control.** No stepping, no software breakpoints, no
|
||||
|
|
|
|||
Loading…
Reference in a new issue