Add support for PDB debugging module
Hello,
I'd like to see support for debugger in Micropython. I know it has been discussed before, but I cannot find any conclusion on that topic from Micropython team. Is even possible to implement PDB support in current Micropython codebase?
If so, what is needed to make it happen? Do the project need more manpower for this task or is it matter of priority or money?
python-ecosys/debugpy: Add VS Code debugging support for MicroPython.
This implementation provides a Debug Adapter Protocol (DAP) server that enables VS Code to debug MicroPython code with full breakpoint, stepping, and variable inspection capabilities.
Features:
- Manual breakpoints via debugpy.breakpoint()
- Line breakpoints set from VS Code
- Stack trace inspection
- Variable scopes (locals/globals)
- Source code viewing
- Stepping (into/over/out)
- Non-blocking architecture for MicroPython's single-threaded environment
- Conditional debug logging based on VS Code's logToFile setting
Implementation highlights:
- Uses MicroPython's sys.settrace() for execution monitoring
- Handles path mapping between VS Code and MicroPython
- Efficient O(n) fibonacci demo (was O(2^n) recursive)
- Compatible with MicroPython's limited frame object attributes
- Comprehensive DAP protocol support
Files:
- README.md: Setup and usage instructions
- debugpy/: Core debugging implementation
- test_vscode.py: VS Code integration test
- dap_monitor.py: Protocol debugging utility
Usage:
import debugpy
debugpy.listen() # Start debug server
debugpy.debug_this_thread() # Enable tracing
debugpy.breakpoint() # Manual breakpoint
🤖 Generated with Claude Code
Currently only tested on unix port with updates to settrace in https://github.com/micropython/micropython/pull/8767
Should work on any network enabled device however?
For those interested in AI coding, this was 95% written by Claude Code (Opus and Sonnet 4) as mentioned in the attributions above. I started prompting the build of this just this morning at 5am from my armchair with my infant asleep in my arms, using Termux on my phone to ssh into my linux box.
I had a clone of micropython with my historical work on getting pdb checked out (https://github.com/micropython/micropython/pull/8767 and https://github.com/micropython/micropython-lib/pull/499)
I also had a copy of the official cpython debugpy package checked out, this is the package used behind the scenes to drive python debugging in VSCode and similar IDE's. From past reviews I knew debugpy relies on threads, the old pydevd network debug engine as well a large RPC server which runs in a thread.
I figured some of this could be re-implemented if needed, or replaced with other servers already running on micropython :-)
So I started with a
claudesession in thedebugpyfolder and performed an initial repo analysis/initbefore asking:Which produced DEBUGPY_ARCHITECTURE_ANALYSIS.md
I then kicked off :
[corona@Telie micropython]$ claude --add-dir ~/debugpy/and gave it this to kick off:
WIthin just 1 hour of armchair vibe coding I had an initial implementation ready to test, along with test scripts and a written plan.
Around 10 am I was at my desk and had finished my morning meetings, so started testing it in the background while working on my other "real" projects.
It tooks quite a few iterations of testing in vscode for Claude to finish its implementation plan, adding features as it ran test scripts with me hitting the vscode "debug" button in between. Most of these tests failed badly in many different ways, enough that I was quite pessimistic at times because it really looked like it wasn't going to work ..... however I was still able to get other solid work done though during this time (which coincidentally was also using Claude Code; I've had 4 sessions actively on the go today) so I gave Claude a few chances to get it all going after a number of wrong paths were backtracked.
After all that though this screen capture was at 2:12 pm (and yes I ate lunch during that time too):

It took me a while to realise while reviewing afterwards and cleaning up the git tree that it hasn't actually pulled in
pdbas a dependency, but re-implemented a simple version of everything needed but not much more; it's a rather minimal implementation!Thanks Andrew,
very nice to see.
It took me more than a few attempts to get this running, but very rewarding.
Perhaps rebasing both PRs to master , and some tweaks fix mismatches in the names of the samples to will help there.
Its good to be able to do a even a simple step -by-step , even though there is now even more to be desired.
Thanks @Josverl good to hear it either for you, I still could hardly believe it worked for me!
I'd be interested to hear any notes about what was confusing / difficult to get going to feed into docs.
I assume some of it was getting paths right to import stuff? And/or compiling with the other features needed? Aka things that'll be better once finished and merged...
I will do some testing on hardware too, ensure that does work and document how to get it going.
I did think the branches were pretty well rebased up to date, I'll double check.
Oh yeah I'll eventually look into getting a useful representation of locals too, even if they end up basically just showing the array of values without names as per the current internal representation.
I first got in a tangle by
blocked most attempts at building as
make submodulesbreaksAfter reverting ./lib/micropython-lib, and cloning this PR to a separate folder things got better
Building a firmware with "the updates to settrace in https://github.com/micropython/micropython/pull/8767"
I still ran into build problems , essentially by a double definition of
MICROPY_PY_SYS_SETTRACE.In the readme of this PR it is part of the instructions , while in the "settrace PR" it is unconditionally defined. These two clash.
Matching up the paths vscode / remote paths, was not to difficult.
Open questions/ more play time needed :
📚 likely relevant : What is the Debug Adapter Protocol?
@andrewleech
I have made some more notes after some additional testing I have done.
I have put them in a Gist notes.md for now as I do not want to drop too many comments here.
Would it make sense to start a Discussion on this topic , or do you prefer everything here ?
Yes the automatic make submodules in mpbuild pretty much breaks development within micropython-lib, I haven't figured out any way to resolve this without a newer/smarter algorithm in the make submodules target (which I haven't written yet)
Ah yeah, the readme in micropython-lib doesn't necessarily know about the updates in the micropython PR,
I haven't figured out the read only src either, it's annoying though. I think it's related to path matching issue between local and remote copies.
Not sure if it is really needed?
The path matching would need to be smart enough to match PC side py to remote module (should be possible) and the mpy would need to have been made with opt=0 otherwise line numbers are stripped.
Ah yeah I didn't actually test that!
Yeah that would be helpful, I'll add it
Definitely a good reference to add to the docs thanks
I did some work to terminate on disconnect
See the PR to your fork
I was able to add (a first rough draft) of support for

frame.f_localson top of the pdb_support branch.Oh wow awesome, I wanted to tackle basically exactly that! Looks great :-D
I was only just about to test my latest changes to this micropython-lib branch; hopefully the read-only window no longer pops up...
Now also able to resolve the names of local variables, at the cost of some memory per frame, and a change in the compiler.
Still a lot of checking and cleanup to do in that part of the code though