3 ms·
I implemented a debugger for an interpreted language (not Python, but similar design problem). I added a C "API" to the interpreter that was designed to be eas
by phaedrus 5y ago
I implemented a debugger for an interpreted language (not Python, but similar design problem). I added a C "API" to the interpreter that was designed to be easily callable via GDB. IIRC it consisted of just three functions: "break on script line", "catch break here", and "why did I break?"
My "debugger" was a shim or wrapper around GDB. For debugging C/C++ code, it just piped standard in/out with GDB. However if it recognized a "set breakpoint" that was actually for a line of script code, it would intercept it. Instead of telling GDB to set a breakpoint there, it would do two things:
It would use GDB to manually call a function in the target program instructing the interpreter to watch for that script line ("set script breakpoint"). Then it would set a normal (native) breakpoint, but in the special function the interpreter would call from its main loop ("catch break here").
Conversely while relaying output from GDB back to the IDE, if it saw it hit a breakpoint in the "catch break here" function, it wouldn't report that. Instead the shim would use GDB to call the "why did I break" function and report the result of that back to the IDE. It was like magic getting to see the IDE bring up the correct script file and line as if the debugger hit it!
Other extensions like single stepping are obvious from these primitives.
- bch 5y agoCurious to hear more about this