#pragma once #include "types.h" struct sbuf; // Asking the kernel a question. // // docs/plan/debugger.md milestone D2. The thing this exists to end is the // ninety-second loop: add a cprintf, rebuild, boot, read the serial log, and // learn the answer to exactly the one question you thought of before the // rebuild. // // The interesting part is not the views. It is that a subsystem publishes its // own state with **one line at the bottom of the file that owns the data**, and // nothing central has to be edited to add one: // // dbg_register("dma", dma_dump, "the DMA arena's free extents"); // // That is the difference between something that stays current and something // that does not. /proc/sysrq is the version that does not -- a switch in one // file with a letter per action, which is why after two years it holds three // self-tests and no state at all. // // Views run in ordinary process context, from a write to /dev/dbg or from // sysrq, so they may take locks. **They must not be called from panic().** // The argument is whatever followed the view's name on the command line, or // "" when there was none. Most views ignore it; the ones that can produce a // hundred lines use it to narrow -- `vma 4` rather than `vma`. It is also the // shape milestone D3 needs, since `whose ` is nothing but an argument. typedef void (*dbg_view_fn)(struct sbuf *out, const char *arg); // Publish a view. `what` is one line, shown by `help`. // // Safe to call from any subsystem's init, in any order: the table is static // and needs no initialisation of its own. void dbg_register(const char *name, dbg_view_fn fn, const char *what); // Run one command line and render the answer. Returns the number of bytes // written into `out`. // // The protocol is lines of text -- see docs/plan/debugger.md for why that and // not a typed binary format. Commands: // // help what this kernel can be asked // all every view, in registration order // [arg] that view, optionally narrowed int dbg_command(const char *line, struct sbuf *out); // Every view, straight to the console. This is what sysrq 'g' runs, and it is // the level-0 path from the plan: no process, no filesystem, no client. void dbg_dump_all(void); #define DBG_MAJOR 10