Conversation
添加位置变动(操作变动)回调接口,为外部实现调试功能实现可能
Introduces JS_SetOPChangedHandler to allow setting a callback for operation changes in the JSContext. Also adds calls to emit_source_loc in various statement parsing locations to improve source location tracking during parsing.
假如没有,位置跟踪会发生异常。
解决在函数内出现静态错误时,返回的堆栈信息中的列号错误的bug。
Introduces functions to get stack depth and retrieve local variables at a specific stack frame level, along with a struct for local variable info and a function to free the allocated array. Also updates the JSOPChangedHandler signature to include JSContext for improved debugging capabilities.
假如采用旧的代码,会发生下面的错误:
function add(a, b){
return a + b;
var b // OP_return会出现在这里
while(1){}
}
add(1, 2)
|
At a quick glance, this looks better than the other approaches I've seen, kudos! Now, since this will have a performance impact, I'd say we want it gated with a compile time time macro. @bnoordhuis thoughts? |
|
Thanks for the feedback @saghul! I've added a compile-time macro Compile-time gating (
|
|
@bnoordhuis WDYT? |
bnoordhuis
left a comment
There was a problem hiding this comment.
Behind a compile-time flag would be good. The diff mostly looks good to me but there are a couple of changes I'd like to see:
-
the API functions should always be available but return an error when compiled without debugger support
-
can you rename the new emit_source_loc calls to something like emit_source_loc_debug and turn that into a no-op when there's no debugger support?
-
I don't love the name JSOPChangedHandler. Suggestions for a better one? Something like JSBytecodeTraceFunc perhaps?
I'm assuming this good enough as a building block to assemble a functional debugger from? I can see how it lets you single-step through code, inspect stack frames, set breakpoints, etc., so I'm guessing... yes?
Rename the old operation_changed/JSOPChangedHandler to bytecode_trace/JSBytecodeTraceFunc and replace JS_SetOPChangedHandler with JS_SetBytecodeTraceHandler. Add conditional compilation guards so debugger-related code is compiled only when QJS_ENABLE_DEBUGGER is set (including stack depth, local-variable APIs, and freeing logic). Introduce emit_source_loc_debug no-op macro when debugger is disabled and make JS_GetStackDepth return -1 without the debugger. Update public header comments to reflect the new API and behavior.
|
Thanks for the review @bnoordhuis! I've addressed all your feedback: 1. API functions always availableType definitions
2. emit_source_loc_debugAdded a macro after emit_source_loc(): All 10 new call sites (for return, let/const, var, if, for, break/continue, switch, try/finally) now use 3. Renamed JSOPChangedHandler →
|
| Old | New |
|---|---|
| JSOPChangedHandler | JSBytecodeTraceFunc |
| JS_SetOPChangedHandler | JS_SetBytecodeTraceHandler |
| ctx->operation_changed | ctx->bytecode_trace |
| ctx->oc_opaque | ctx->trace_opaque |
4. Re: building block for a functional debugger
Yes — the current API covers the essential building blocks: single-step, breakpoints, call stack inspection, and local variable read access. I've built a working VSCode debugger on top of it QuickJS-Debugger
For a more complete debugger experience, a few additional APIs could be added later (as separate PRs):
- JS_EvalInStackFrame() — eval an expression in a specific frame's scope
- Closure variable access (captured vars from outer scopes)
- Exception hook (pause on throw)
But these can be built incrementally. The current PR is a solid minimal foundation.
|
I'm reasonably confident we can support this at runtime, no compile-time flags, without significant slowdowns when the debugger is inactive:
Proof of concept, very WIP: bnoordhuis/quickjs@f5fbb5b |
Add a debugging interface to the existing architecture.

Using the added debugging interface, we implemented debugging for QuickJS in VSCode. The project address is:[QuickJS-Debugger]