Skip to content

Commit 5e1e259

Browse files
mfusseneggerKatzeee
andcommitted
Jump on stopped event if same threadId is already marked as stopped
Some debug adapters allow to resume execution using custom evaluate commands. This unfortunately by-passes some logic that puts the client into "running" state again. If the client then receives a stopped event it assumed it was already stopped and sent a continue request (unless `auto_continue_if_many_stopped` was disabled) This changes the condition to also jump if `stopped_thread_id == stopped.threadId` Closes #898 Co-authored-by: xac <[email protected]>
1 parent a5b059e commit 5e1e259

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

lua/dap/session.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ local function launch_external_terminal(terminal, args)
132132
detached = true
133133
}
134134
handle, pid_or_err = uv.spawn(terminal.command, opts, function(code)
135-
handle:close()
135+
if handle then
136+
handle:close()
137+
end
136138
if code ~= 0 then
137139
utils.notify(string.format('Terminal exited %d running %s %s', code, terminal.command, table.concat(full_args, ' ')), vim.log.levels.ERROR)
138140
end
@@ -641,7 +643,11 @@ function Session:event_stopped(stopped)
641643
end
642644

643645
local should_jump = stopped.reason ~= 'pause' or stopped.allThreadsStopped
644-
if self.stopped_thread_id and should_jump then
646+
647+
-- Some debug adapters allow to continue/step via custom REPL commands (via evaluate)
648+
-- That by-passes `clear_running`, resulting in self.stopped_thread_id still being set
649+
-- Dont auto-continue if`threadId == self.stopped_thread_id`, but stop & jump
650+
if self.stopped_thread_id and self.stopped_thread_id ~= stopped.threadId and should_jump then
645651
if defaults(self).auto_continue_if_many_stopped then
646652
local thread = self.threads[self.stopped_thread_id]
647653
local thread_name = thread and thread.name or self.stopped_thread_id

tests/integration_spec.lua

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,42 @@ describe('dap with fake server', function()
159159
assert.are.same(expected, diagnostics)
160160
end)
161161

162+
it('jumps to location if thread with same id is already stopped', function()
163+
local session = run_and_wait_until_initialized(config, server)
164+
165+
-- Pretend to be stopped
166+
session.stopped_thread_id = 1
167+
168+
server.spy.clear()
169+
server.client.threads = function(self, request)
170+
self:send_response(request, {
171+
threads = { { id = 1, name = 'thread1' }, }
172+
})
173+
end
174+
server.client.stackTrace = function(self, request)
175+
self:send_response(request, {
176+
stackFrames = {
177+
{
178+
id = 1,
179+
name = 'stackFrame1',
180+
line = 1,
181+
},
182+
},
183+
})
184+
end
185+
session:event_stopped({
186+
allThreadsStopped = false,
187+
threadId = 1,
188+
reason = 'breakpoint',
189+
})
190+
vim.wait(1000, function() return #server.spy.requests == 3 end)
191+
local expected_commands = {"threads", "stackTrace", "scopes"}
192+
assert.are.same(
193+
expected_commands,
194+
vim.tbl_map(function(x) return x.command end, server.spy.requests)
195+
)
196+
end)
197+
162198
it('jumps to location on stopped with reason=pause and allThreadsStopped', function()
163199
local session = run_and_wait_until_initialized(config, server)
164200
server.spy.clear()

0 commit comments

Comments
 (0)