As mentioned Will the Befaco Oneiroi be coming to the 4ms Meta?, I’ve been setting up a way to debug using an AI agent to assist with the process (as I’m not super familiar with GDB), and thought I’d share. Fair warning, the tool is “YOLO” by default.
Setup
I’ve used a few agentic tools in the past but have recently being enjoying the minimal pi agent. There’s a great article from the developer here, and one example he shows is using gdb to debug a faulty c program using tmux.
It works well if you set up SKILLS for some common tasks, and I found some good starter skills in this repo, including one that teaches the agent how to use tmux: agent-stuff/skills/tmux/SKILL.md at main · mitsuhiko/agent-stuff · GitHub (also good uv skill).
Then I connected my STLINK-V3MINIE probe to the MM board following the instructions here for JTAG (i.e. add freeze jumper and wire up to JTAG header. Then in one window, in source checkout in firmware directory make start-openocd and in a new tmux session in theory we run make debug, or so I thought! In practice I found Ctrl-C commands, which interrupt the running program in gdb, get intercepted by cmake and then cmake quits (ending gdb session) - @danngreen not sure if you can reproduce, and if so maybe we can update docs? Anyway I had to run cmake to build the image then run gdb seperately:
# in a tmux session
# build only
cmake --build --preset full -- main.uimg
# launch gdb
/Applications/ArmGNUToolchain/12.3.rel1/arm-none-eabi/bin/arm-none-eabi-gdb --command=flashing/multi.gdbinit
This will load the MM image into memory directly, and takes about 2 mins each time you want to do it! It will drop you into (gdb) prompt if sucessful.
Debugging with pi
Assuming pi has the tmux skill installed, you can simply run pi in the metamodule checkout and instruct in plain langauge:
Me: Following @docs/ i’ve started openocd with make start-openocd in one window and in tmux i’ve loaded firmware with make debug, tmux session named metamodule_session. can you attach and manipulate gdb? lets test continue and break to start.
…
tmux capture-pane -p -J -t metamodule_session:0.0 -S -120
…
tmux send-keys -t metamodule_session:0.0 -- 'continue' Enter; sleep 1; tmux send-keys -t metamodule_session:0.0 C-c; sleep 1; tmux capture-pane -p -J -t metamodule_session:0.0 -S -80
Done — I attached to your existing
gdbin tmux sessionmetamodule_sessionand ran the test sequence.What I sent
continueCtrl-C(break/interrupt)Result
GDB resumed and then halted cleanly on interrupt:
Program received signal SIGINT, Interrupt.- Current stop PC:
0xc2340a8c- Current frame:
std::__atomic_base<bool>::load(...)inatomic_base.h:486So continue/break control is working from my side.
If you want, next I can:
- set a breakpoint at a specific function (
break <symbol>)- do
bt/ inspect locals- continue until that breakpoint and verify hit behavior.
Then from that point on I would try hypotheses for the bug and the agent would place break points etc
(gdb) break OneiroiVCV::process
continue
Breakpoint 1 at 0xc249bfb0: file /Users/ewanhemingway/Documents/Code/VCV/OneiroiMetaModule/befaco-oneiroi/src/Oneiroi.cpp, line 802.
(gdb) continue
Continuing.
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x8000011f pc: 0xc239daf4
MMU: enabled, D-Cache: enabled, I-Cache: enabled
Breakpoint 1, OneiroiVCV::process (this=0xcd546740, args=...) at /Users/ewanhemingway/Documents/Code/VCV/OneiroiMetaModule/befaco-oneiroi/src/Oneiroi.cpp:802
802 if (!patch || !bufferIn || !bufferOut) {
(gdb)
For example here it is dumping out oscillator volumes etc:
tmux send-keys -t metamodule_session:0.0 -- 'frame 0' Enter; tmux send-keys -t metamodule_session:0.0 -- 'print patchCtrls->oscUseWavetable' Enter; tmux send-keys -t metamodule_session:0.0 -- 'print ui->osc2Vol_' Enter; sleep 0.8; tmux capture-pane -p -J -t metamodule_session:0.0 -S -60
Bug solved
In this case, I got silence in a simple patch with just sawtooth up (no filter etc), but would get sound after randomising a few times. We added diagnostics to the plugin, and dumped all parameters to file in working and non-working case. Eventually the agent spotted NaNs in one of the filter sections, and even though filter was completely dry, the NaNs still infected the audio chain. So we worked out it was due to MM 32kHz sample rate and some filter cutoffs over Nyquist, which were promptly fixed!
Any questions happy to answer! I think most of this would work with other setups, key thing is the agent being able to grab the tmux output with capture-pane and send arbitrary commands to tmux via send-keys, the rest it can piece together.