From aa248658cf12d1e49b37a3ee6f19b3ecced0fee0 Mon Sep 17 00:00:00 2001 From: denin Date: Tue, 31 Oct 2023 22:56:13 +0300 Subject: [PATCH] dap-python: Support attach to an existing process - New configuration attribute `processId` is added. This name is picked to provide a consistent interface for both debugpy and ptvsd as well as make it works with launch.json naturally. --- dap-python.el | 26 ++++++++++++++++++-------- docs/page/configuration.md | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/dap-python.el b/dap-python.el index 4eb6b590..4c44ae11 100644 --- a/dap-python.el +++ b/dap-python.el @@ -177,7 +177,8 @@ strings, for the sake of launch.json feature parity." (plist-get conf :program) (buffer-file-name))) (module (plist-get conf :module)) - (debugger (plist-get conf :debugger))) + (debugger (plist-get conf :debugger)) + (targetPid (plist-get conf :processId))) ;; These are `dap-python'-specific and always ignored. (cl-remf conf :debugger) (cl-remf conf :target-module) @@ -196,14 +197,17 @@ strings, for the sake of launch.json feature parity." (cl-remf conf :module) (cl-remf conf :args) (plist-put conf :program-to-start - (format "%s%s -m ptvsd --wait --host %s --port %s%s %s%s" + (format "%s%s -m ptvsd --wait --host %s --port %s %s" (or dap-python-terminal "") (shell-quote-argument python-executable) host debug-port - (if module (concat " -m " (shell-quote-argument module)) "") - (if program (shell-quote-argument program) "") - (if (not (string-empty-p python-args)) (concat " " python-args) ""))) + (if targetPid + (format "--pid %s" targetPid) + (format "%s %s %s" + (if module (concat " -m " (shell-quote-argument module)) "") + (if program (shell-quote-argument program) "") + (if (not (string-empty-p python-args)) (concat " " python-args) ""))))) (plist-put conf :debugServer debug-port) (plist-put conf :port debug-port) (plist-put conf :hostName host) @@ -235,11 +239,12 @@ strings, for the sake of launch.json feature parity." (unless (plist-get conf :cwd) (cl-remf conf :cwd)) - (pcase (plist-get conf :request) - ("launch" + (pcase (cons (plist-get conf :request) targetPid) + ((or `("launch" . nil) + `("attach" . ,(and pid (guard pid)))) (plist-put conf :dap-server-path (list python-executable "-m" "debugpy.adapter"))) - ("attach" + (`("attach" . nil) (let* ((connect (plist-get conf :connect)) (host (or (plist-get connect :host) "localhost")) (port (or (plist-get connect :port) 5678))) @@ -260,6 +265,11 @@ strings, for the sake of launch.json feature parity." (dap-python--populate-start-file-args conf)) (dap-register-debug-provider "python" 'dap-python--populate-start-file-args) +(dap-register-debug-template "Python :: Attach to running process" + (list :type "python" + :request "attach" + :processId "${command:pickProcess}" + :name "Python :: Attach to running process")) (dap-register-debug-template "Python :: Run file (buffer)" (list :type "python" :args "" diff --git a/docs/page/configuration.md b/docs/page/configuration.md index 11629577..88cd918b 100644 --- a/docs/page/configuration.md +++ b/docs/page/configuration.md @@ -182,6 +182,27 @@ These parameters are handled by templates of type `python`: Remaining parameters are forwarded to the respective debugger. +4. Attach to an existing process + `dap-python` supports also the "attach" mode to attach and debug a long running script. + A template named "Python :: Attach to running process" is also pre-registered for this purpose. + ```elisp + (dap-register-debug-template "Python :: Attach to running process" + (list :type "python" + :request "attach" + :processId "${command:pickProcess}" + :name "Python :: Attach to running process")) + ``` + The `${command:pickProcess}` configuration variable used by default to facilitate the user + selecting the debug process by a completion popping up window. The real `processId` can + always be specified using its *pid*. + **Note**: on Linux this is achieved using the [ptrace syscall](https://www.man7.org/linux/man-pages/man2/ptrace.2.html "ptrace syscall man page") + wrapped inside the GDB tool, which means that for distributions that enable YAMA (e.g. Ubuntu) some additional steps may be necessary: + - Install GDB. + - Turn on classic ptrace permission + ```bash + sudo sh -c 'echo 0 > /proc/sys/kernel/yama/ptrace_scope' + ``` + ## Ruby