Open wztdream opened 4 years ago
@yyoncho I try to implement dap-run-to-cursor
by wrapping dap-breakpoint-add
dap-continue
and dap-breakpoint-delete
(defun dap-run-to-cursor ()
"Run to cursor"
(interactive)
(save-excursion
(call-interactively #'dap-breakpoint-add)
(call-interactively #'dap-continue)
)
(call-interactively #'dap-breakpoint-delete)
)
But results in error:
Debugger entered--Lisp error: (wrong-type-argument overlayp nil)
delete-overlay(nil)
mapc(delete-overlay (nil #<overlay from 1 to 9 in dap-test.py> #<overlay from 10 to 18 in dap-test.py>))
dap-ui--clear-breakpoint-overlays()
dap-ui--refresh-breakpoints()
run-hooks(dap-breakpoints-changed-hook)
dap--update-breakpoints(#s(dap--debug-session :name "Python :: Run file (buffer)" :last-id 34 :proc #<process Python :: Run file (buffer)> :response-handlers #<hash-table eql 2/65 0x158b1615ecc5> :parser #s(dap--parser :waiting-for-response nil :response-result nil :headers nil :body nil :reading-body nil :body-length nil :body-received nil :leftovers "") :output-buffer #<buffer *Python :: Run file (buffer) out*> :thread-id 1 :workspace nil :threads (#<hash-table equal 2/65 0x158b168d7ced>) :thread-states #<hash-table eql 1/65 0x158b161683bd> :active-frame-id nil :active-frame nil :cursor-marker nil :state running :breakpoints #<hash-table equal 1/65 0x158b16168695> :thread-stack-frames #<hash-table eql 0/65 0x158b161686b5> :launch-args (:type "python" :request "launch" :name "Python :: Run file (buffer)" :args [] :dap-server-path ("/home/wangzongtao/anaconda3/envs/py36/bin/python" "-m" "debugpy.adapter") :program "/home/wangzongtao/research/code/temp/dap-test.py") :initialize-result #<hash-table equal 6/65 0x158b1613a055> :error-message nil :loaded-sources nil :program-proc nil :metadata #<hash-table eql 0/65 0x158b161686d5> :output-displayed nil) #<hash-table equal 6/65 0x158b170d8209> "/home/wangzongtao/research/code/temp/dap-test.py")
#f(compiled-function (resp) #<bytecode 0x158b16fd537d>)(#<hash-table equal 6/65 0x158b170d8209>)
#f(compiled-function (input0) #<bytecode 0x158b16fd5399>)(#<hash-table equal 6/65 0x158b170d8209>)
#f(compiled-function (m) #<bytecode 0x158b17028af1>)("{\"seq\": 51, \"type\": \"response\", \"request_seq\": 33,...")
mapc(#f(compiled-function (m) #<bytecode 0x158b17028af1>) ("{\"seq\": 45, \"type\": \"response\", \"request_seq\": 31,..." "{\"seq\": 46, \"type\": \"response\", \"request_seq\": 32,..." "{\"seq\": 47, \"type\": \"event\", \"event\": \"output\", \"b..." "{\"seq\": 48, \"type\": \"event\", \"event\": \"continued\",..." "{\"seq\": 49, \"type\": \"event\", \"event\": \"stopped\", \"..." "{\"seq\": 50, \"type\": \"event\", \"event\": \"output\", \"b..." "{\"seq\": 51, \"type\": \"response\", \"request_seq\": 33,..."))
#f(compiled-function (_ msg) #<bytecode 0x158b1615f529>)(#<process Python :: Run file (buffer)> "Content-Length: 528\15\n\15\n{\"seq\": 45, \"type\": \"respon...")
So, where am I wrong?
(defun dap-run-to-cursor () "Run to cursor" (interactive) (save-excursion (call-interactively #'dap-breakpoint-add) (call-interactively #'dap-continue) ) (call-interactively #'dap-breakpoint-delete) )
This wont work since dap-breakpoint-add/continue are async operations. Generally, I don't think that this functionality can be implemented without server support.
So DAP server does not support this function?
But I do see the run-to-cursor
function in vscode, and I noticed that it temporally added and deleted a break-point (a break point appear and disappear quickly in break point window), so it seems vscode achieve this by just add and deleted the break point.
Thank you, but it seems this beyond my ability. I have only limited elisp knowledge and I do not understand how dap-mode handle the request and responds. Maybe someone are interested to implement it, it should be useful.
Goto has nothing to do with this afaics - it allows moving the instruction pointer to some line of code, skipping things. This isn't what we need. I do believe that this can be implemented without debugger support - we need to add callbacks to breakpoints, and the ability to make breakpoints invisible. This way, an invisible, self-deleting breakpoint could be added.
But there will be lots of refactoring to do - breakpoints are plists, not structures sadly.
Actually, this could be even simpler; dap-breakpoint-add with dap-breakpoint-delete in the async body.
I just tried and failed: we need callbacks. Here is my (failed) attempt for anyone interested:
(defun dap-run-until (session pos file)
"Continue until the cursor is hit."
(interactive (list (dap--cur-session-or-die) (point) (buffer-file-name)))
(let ((file-breakpoints (gethash file (dap--get-breakpoints)))
(new-bp (list :point pos)))
(dap--send-message
(dap--set-breakpoints-request file (cons new-bp file-breakpoints))
(dap--resp-handler
(lambda (_) (dap--send-message
(dap--set-breakpoints-request file file-breakpoints)
(dap--resp-handler) session))) session)))
But there will be lots of refactoring to do - breakpoints are plists, not structures sadly.
That should be fine.
I checked vscode and it is using breakpoints but their solution does not work the way run to cursor works in the IDEs.
@yyoncho 2: we could temporarily disable all breakpoints, but not display that in the GUI. 1: this will be a problem.
Does dap have thread-local breakpoints?
We cannot disable temporary the breakpoints because this will affect other threads. There are no thread local breakpoints. We could have ad-hoc solution like VScode
But what are are the limitations of VSCode's solution? Does it work in multithreaded programs, does the program break on other breakpoints? If not, then I have one more final idea: we can have a temporary breakpoints whitelist, which maps threads to the breakpoints that are allowed to break them, coupled with adding an :invisible property to breakpoints. If we hit any other breakpoints, we just issue a continue request and ignore them one dap's side.
AFAICS their solution is simple:
But that means that the current thread would be stopped when hitting other breakpoints, and that other threads could be stopped too, or am I missing something?
But that means that the current thread would be stopped when hitting other breakpoints, and that other threads could be stopped too, or am I missing something?
Yes. The question is whether their solution is good enough from a practical point of view or we should spend more effort on implementing what you have described above.
Hi, Thank you all for this great package! It will be handy if dap-mode can add
debug-to-here
function, I know we can add and remove break point for this purpose, but it will be convenient for the users to make it auto, move cursor to some line, thendebug-to-here
, that is great.Sometimes we need to move our cursor around during debug, to check some code for example, I always get lost and can not find where is current debug step, it will be useful to have a function
go-back-to-current-debug-step
to jump back to current debug step.