* Debugging Guix beyond pk Ludovic Courtès <2023-02-03 Fri 16:30> ** Emacs: Geiser - Start the Guile REPL in Emacs with =M-x geiser=. - Geiser also has limited support for debugging, check out its manual. (~geiser-debug-mode~?) Here, we just used the Guile REPL. - When you open a Guix/Guile file in Emacs with Geiser and ~guix-devel-mode~ enabled, type =C-c . u= (which runs ~guix-devel-use-module~) to then be able to use =M-.= to jump to the definition of an identifier. ** ~pk~ - ~pk~ is simple Guile function which you can wrap around anything. It will print and return its argument. - Guile will also assign that value to a variable, e.g. ~$5~. - You can wrap an expression ~(some expression)~ to ~(pk 'this-is-where-i-want-to (some expression))~. ** REPL basics - Use comma-prefixed commands ~,use (guix)~ or ~,use (gnu packages base)~ to import a module. - Once you are using the ~(guix)~ module, you can type ~,help guix~ to get some guix-specific commands (not functions, but REPL-commands!). - You can use one of those guix-specific REPL-command, e.g. ~,build coreutils~. - In Emacs, you can run the interactive ~find-file~ on a store-item-path. (If you have performance problems because Emacs reads the content of =/gnu/store=, then copy the path and insert it into =M-: (find-file "HERE")=). - Use the ~,lower coreutils~ command to get a derivation. Then you can run ~find-file~ on the ~/gnu/store/…-builder~. In that buffer, you can run ~M-x guix-scheme-mode~ to format the parantheses! Killer feature! ** Difference between ~guile~ and ~guix repl~ - ~%load-path~ - Some auto-compile configuration (?) ** Breakpoints - ~(define s (open-connection))~ connects to the Guix daemon. ~s~ is the store. - ~,use(guix packages)~ - ~,break package-bag~ sets a breakpoint around the ~package-bag~ function - When you now run ~(package-derivation s coreutils)~, Guile recursively start a REPL at that breakpoint, indicated with an ~[1]~ in the prompt. - Use ~,bt~ in that breakpoint-REPL to get a backtrace. (In the backtrace, tail-calls won't occur.) - In the backtrace, we can see each stack-frame listed in a numbered list - ~,locals~ will list local variables at the breakpoint (if they haven't been optimized away) - ~,frame 1~ enters the stack-frame 1 - You can inspect e.g. the seventh local variable called ~$7~ with ~,inspect $7~ - Within the inspect-REPL, you can view the guile-vm-code with ~x~ - Exit the inspect-REPL with ~q~ - Use ~,next-instruction~ (or ~,ni~) to see which instruction would be executed next - There is also ~,next~ which works at the language level. Afterwards you could again print a backtrace. - ~,traps~ shows the set of currently attached traps (breakpoints and tracepoints). - ~,q~ will quit the breakpoint-REPL - ~,delete 0~ will delete the zeroth breakpoint ** Pretty-printing - Use ~,pp thing~ for pretty-printing - ~,pp (package-arguments coreutils)~ will pretty-print the package's ~arguments~-field, i.e. the arguments to the ~gnu-build-system~. - ~,pp (parameterize ((%current-system "i586-gnu")) (package-arguments coreutils))~ will show you those package-arguments as if you were running GNU Hurd - (~parameterize~ is a generic Guile syntax for introducing dynamic scoping.)