-
Notifications
You must be signed in to change notification settings - Fork 33
[see #168] Changes to debugger for runtime inspector #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
86c465c
9284eb5
f87ee89
37ae99e
1fdf65d
40d3a63
608dcd0
802b48b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -152,7 +152,14 @@ DebuggerScope* DebuggerCallFrame::scope(VM& vm) | |||||||||||||||||||||||||||||||||||||
| CodeBlock* codeBlock = m_validMachineFrame->isNativeCalleeFrame() ? nullptr : m_validMachineFrame->codeBlock(); | ||||||||||||||||||||||||||||||||||||||
| if (isTailDeleted()) | ||||||||||||||||||||||||||||||||||||||
| scope = m_shadowChickenFrame.scope; | ||||||||||||||||||||||||||||||||||||||
| else if (codeBlock && codeBlock->scopeRegister().isValid()) | ||||||||||||||||||||||||||||||||||||||
| // Code compiled without CodeGenerationMode::Debugger may have its scope | ||||||||||||||||||||||||||||||||||||||
| // register repurposed by the DFG (DFGStackLayoutPhase invalidates it when | ||||||||||||||||||||||||||||||||||||||
| // needsScopeRegister() is false). Reading the scope register from such a | ||||||||||||||||||||||||||||||||||||||
| // frame crashes because the slot contains stale data (e.g., a VirtualRegister | ||||||||||||||||||||||||||||||||||||||
| // offset instead of a JSScope pointer). ShadowChicken has the same guard. | ||||||||||||||||||||||||||||||||||||||
| // Falls through to callee->scope() which is always valid. | ||||||||||||||||||||||||||||||||||||||
| else if (codeBlock && codeBlock->scopeRegister().isValid() | ||||||||||||||||||||||||||||||||||||||
| && codeBlock->wasCompiledWithDebuggingOpcodes()) | ||||||||||||||||||||||||||||||||||||||
| scope = m_validMachineFrame->scope(codeBlock->scopeRegister().offset()); | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+155
to
163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify wasCompiledWithDebuggingOpcodes is declared on CodeBlock and check its semantics
rg "wasCompiledWithDebuggingOpcodes" -C 3 --type cpp --type hRepository: oven-sh/WebKit Length of output: 6185 🏁 Script executed: #!/bin/bash
# Check needsScopeRegister relationship with debugging opcodes
rg "needsScopeRegister" -C 3 --type cpp --type h | head -100Repository: oven-sh/WebKit Length of output: 4204 🏁 Script executed: #!/bin/bash
# Locate CodeBlock.h to inspect the method declaration
fd "CodeBlock.h" --type fRepository: oven-sh/WebKit Length of output: 697 Core guard is correct — minor readability nit on condition ordering. The fix is sound: guarding the scope-register read with One readability nit: the semantic primary guard is ♻️ Optional reordering for clarity- else if (codeBlock && codeBlock->scopeRegister().isValid()
- && codeBlock->wasCompiledWithDebuggingOpcodes())
+ else if (codeBlock && codeBlock->wasCompiledWithDebuggingOpcodes()
+ && codeBlock->scopeRegister().isValid())📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| else if (JSCallee* callee = jsDynamicCast<JSCallee*>(m_validMachineFrame->jsCallee())) | ||||||||||||||||||||||||||||||||||||||
| scope = callee->scope(); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,6 +29,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "CallFrameInlines.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "CodeBlock.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "CodeBlockSet.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "Debugger.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "DFGCommonData.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "ExceptionHelpers.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "HeapInlines.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -46,6 +47,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <wtf/ThreadMessage.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <wtf/threads/Signals.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if USE(BUN_JSC_ADDITIONS) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extern "C" __attribute__((weak)) void Bun__drainQueuedCDPMessages(JSC::VM&); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extern "C" __attribute__((weak)) bool Bun__shouldBreakAfterMessageDrain(JSC::VM&); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace JSC { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if ENABLE(SIGNAL_BASED_VM_TRAPS) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -474,9 +480,28 @@ bool VMTraps::handleTraps(VMTraps::BitField mask) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool didHandleTrap = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (needHandling(mask)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto event = takeTopPriorityTrap(mask); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (event == NoEvent) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch (event) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case NeedDebuggerBreak: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| invalidateCodeBlocksOnStack(vm.topCallFrame); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if USE(BUN_JSC_ADDITIONS) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Drain queued CDP messages. If a command like Debugger.pause | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // is dispatched, it sets m_javaScriptPauseScheduled on the agent. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (Bun__drainQueuedCDPMessages) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bun__drainQueuedCDPMessages(vm); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only enter breakProgram() if a pause was actually requested | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // (bootstrap, Debugger.pause command, breakpoint). For plain | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // message delivery, the drain above is sufficient. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Bun__shouldBreakAfterMessageDrain || Bun__shouldBreakAfterMessageDrain(vm)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (vm.topCallFrame) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (auto* globalObject = vm.topCallFrame->lexicalGlobalObject(vm)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (auto* debugger = globalObject->debugger()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| debugger->breakProgram(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| didHandleTrap = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
486
to
506
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check git history for VMTraps.cpp
cd Source/JavaScriptCore/runtime
git log --oneline -n 30 VMTraps.cppRepository: oven-sh/WebKit Length of output: 123 🏁 Script executed: #!/bin/bash
# Get the detailed diff for the NeedDebuggerBreak case to see what changed
git show HEAD -- Source/JavaScriptCore/runtime/VMTraps.cpp | grep -A 40 -B 5 "NeedDebuggerBreak"Repository: oven-sh/WebKit Length of output: 1974 🏁 Script executed: #!/bin/bash
# Check the previous version to see the original implementation
git show HEAD~1:Source/JavaScriptCore/runtime/VMTraps.cpp 2>/dev/null | sed -n '480,510p' || echo "Previous version not available or file path differs"Repository: oven-sh/WebKit Length of output: 40 🏁 Script executed: #!/bin/bash
# Check the parent commit to see original code
git show HEAD~1:Source/JavaScriptCore/runtime/VMTraps.cpp | grep -A 20 "NeedDebuggerBreak" | head -30Repository: oven-sh/WebKit Length of output: 94 🏁 Script executed: #!/bin/bash
# Also check if NeedDebuggerBreak existed at all before
git log --all -S "NeedDebuggerBreak" --oneline -- Source/JavaScriptCore/runtime/VMTraps.cpp | head -10Repository: oven-sh/WebKit Length of output: 424 🏁 Script executed: #!/bin/bash
# Get more context - what does the current file look like in full context?
git show HEAD:Source/JavaScriptCore/runtime/VMTraps.cpp | sed -n '480,520p'Repository: oven-sh/WebKit Length of output: 1771 🏁 Script executed: #!/bin/bash
# Find all references to NeedDebuggerBreak
rg "NeedDebuggerBreak" --type cpp --type h -B 3 -A 3Repository: oven-sh/WebKit Length of output: 6042 🏁 Script executed: #!/bin/bash
# Check the enum definition for trap events
rg "enum.*Trap|NeedDebuggerBreak" Source/JavaScriptCore/runtime/VMTraps.h -B 5 -A 5Repository: oven-sh/WebKit Length of output: 1453 🏁 Script executed: #!/bin/bash
# Search for any unconditional breakProgram calls in the trap handler
rg "breakProgram" Source/JavaScriptCore/runtime/VMTraps.cpp -B 2 -A 2Repository: oven-sh/WebKit Length of output: 621 🏁 Script executed: #!/bin/bash
# Check how USE(BUN_JSC_ADDITIONS) is defined
rg "define.*USE.*BUN_JSC_ADDITIONS|#if.*USE.*BUN_JSC_ADDITIONS" -B 2 -A 2 | head -40Repository: oven-sh/WebKit Length of output: 2516 🏁 Script executed: #!/bin/bash
# Check if this code is meant to work without Bun additions
rg "NeedDebuggerBreak" Source/WebKit -A 5 -B 5 | grep -A 10 -B 10 "notifyNeedDebuggerBreak"Repository: oven-sh/WebKit Length of output: 3260 🏁 Script executed: #!/bin/bash
# Look for similar patterns - how do other trap handlers handle conditional code?
rg "case Need" Source/JavaScriptCore/runtime/VMTraps.cpp -A 15 | head -80Repository: oven-sh/WebKit Length of output: 2202 The entire WebKit's Unlike other trap handlers (NeedShellTimeoutCheck, NeedWatchdogCheck, NeedTermination, NeedStopTheWorld, NeedExceptionHandling), which all execute unconditionally, this is the only handler with core functionality guarded. The Bun-specific parts (CDP message draining, the Add an Proposed fix }
}
`#endif`
+#else
+ if (vm.topCallFrame) {
+ if (auto* globalObject = vm.topCallFrame->lexicalGlobalObject(vm)) {
+ if (auto* debugger = globalObject->debugger())
+ debugger->breakProgram();
+ }
+ }
+#endif
didHandleTrap = true;
break;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.