Inline Session
A complete inline BPF session -- compilation, loading, attachment, and event consumption in a single Lisp file, with no separate compilation step.
Full example
(asdf:load-system "whistler/loader")
(in-package #:whistler-loader-user)
;;; Struct definition -- generates both BPF and CL sides
(whistler:defstruct call-event
(pid u32)
(ts u64))
;;; Inline BPF session
(defun run ()
(with-bpf-session ()
;; BPF side (compiled at macroexpand time)
(bpf:map events :type :ringbuf :max-entries 4096)
(bpf:prog trace-exec (:type :kprobe
:section "kprobe/__x64_sys_execve"
:license "GPL")
(with-ringbuf (ev events (sizeof call-event))
(setf (call-event-pid ev) (cast u32 (ash (get-current-pid-tgid) -32))
(call-event-ts ev) (ktime-get-ns)))
0)
;; Userspace side (runs at runtime)
(bpf:attach trace-exec "__x64_sys_execve")
(with-decoding-ring-consumer (consumer
(bpf-session-map 'events)
#'decode-call-event
(lambda (ev)
(format t "exec pid=~d ts=~d~%"
(call-event-record-pid ev)
(call-event-record-ts ev))))
(handler-case
(loop (ring-poll consumer :timeout-ms 1000))
(sb-sys:interactive-interrupt ()
(format t "~&Detaching.~%"))))))
(run)
Run:
sudo sbcl --load my-tracer.lisp
Key points
-
Lifecycle:
with-bpf-sessionmanages the full BPF lifecycle. Maps, programs, and attachments are created on entry and cleaned up on exit.with-decoding-ring-consumerhandles ring consumer cleanup even on Ctrl-C. -
bpf: prefix:
bpf:mapandbpf:progare compiled at macroexpand time.bpf:attachandbpf:map-refexpand to runtime loader calls. Everything else is plain CL code that runs at load time. -
Package setup:
whistler-loader-useris the intended default package for interactive work. It already imports the compiler and loader symbols with the right shadowing in place. -
Map access:
*bpf-session*is a special variable bound during the session. Usebpf-session-mapfor named lookup:(bpf-session-map 'events)For simple integer reads,
(bpf:map-ref map-name key)is more convenient. For struct-valued maps, usemap-lookup-struct-intandmap-update-struct-intwith the generated record codecs.