ç¶ã
GNU Emacs 㧠VS Code ç¸å½ã®ã³ã¼ãã»ãããã°æ¯æ´æ©è½ãè¨å®ãã (1) â Eglot ããã®ç¶ãã§ãã
Dape
ã¤ã³ã¹ãã¼ã«
Emacs ã®ããã±ã¼ã¸ ããã¼ã¸ã£ã¼ã§ã¤ã³ã¹ãã¼ã«ã§ãã¾ãã
M-x package-install RET dape RET
ãã¦ã¹ã§ãã¬ã¼ã¯ãã¤ã³ããã»ããã§ããããã«ãã¦ããã¾ããã¾ã repeat-mode
ãæå¹ã«ãã¾ãã
~/.emacs.d/init.el
(use-package dape :bind-keymap ("C-x C-a" . dape-global-map) :config ;; Global bindings for setting breakpoints with mouse (dape-breakpoint-global-mode)) ;; Enable repeat mode for more ergonomic `dape' use (use-package repeat :config (repeat-mode))
DAP ã¢ããã¿ã¼
ãµãã¼ãããã¦ãã DAP ã¢ããã¿ã¼ã®æ å ±ã¯ Supported debug adapters ã«ããã¾ãã
C/C++
- GDB >=14.1
- arm64 macOS ããµãã¼ããã¦ããªã
- codelldb
- cpptools
- ã©ã¤ã»ã³ã¹ ãå¾®å¦
- lldb-dap
ããã§ã¯ codelldb 㨠lldb-dap ãé¸ã³ã¾ãã
codelldb
VS Code ã VSCodium ã® Extensions ãã CodeLLDB ãã¤ã³ã¹ãã¼ã«ãã¦ãªã³ã¯ãå¼µãæ¹ãã¢ãããã¼ãã macOS ãåºãã¦ããã»ãã¥ãªãã¤è¦åã¸ã®å¯¾å¿ã容æã ã¨æãã¾ãã
% cd ~/.emacs.d/debug-adapters/codelldb % ln -s ../../../.vscode-oss/extensions/vadimcn.vscode-lldb-1.11.0-universal
lldb-dap
macOS ã® the command line developer tools ã«ä»å±ã®ãã®ã使ãã¾ãããã ãããã©ã«ã㧠$PATH
ãéã£ã¦ããªãã®ã§éã£ã¦ãããã£ã¬ã¯ããªã¼ãããªã³ã¯ãå¼µã£ã¦ããã¾ãã
% cd ~/.local/bin % ln -s "$(xcrun --find lldb-dap)" .
Python
Homebrew ã«ã¯ debugpy ãè¦å½ãããªãã®ã¨ã¢ã¸ã¥ã¼ã«ã¨ãã¦ä½¿ç¨ããããã pipx
ã使ããªãã®ã§ pip
ã§ã¤ã³ã¹ãã¼ã«ãããããªãããã§ãããã ã PEP 668 and virtual environments ã«å¾ã "virtual environment" ã使ãã¾ãã 12. Virtual Environments and Packages ã VS Code ã® Create a virtual environment ãåèã«ãã¤ã¤ãã¨ãã°
% python3 -m venv ~/Developer/python/tutorial/.venv % source ~/Developer/python/tutorial/.venv/bin/activate (.venv) % python3 -m pip install debugpy (.venv) % deactivate %
Python venv ã§ã® Emacs ã®èµ·å
debugpy ã "system-wide" ã«ã¤ã³ã¹ãã¼ã«ããã¦ããç°å¢ãªã Emacs.app ããã¹ã¯ãããããèµ·åãã¦ãããã¯ãã§ãã "virtual environment" ã®å ´å㯠source activate
ãã shell ãã emacs
ã èµ·åããªã㨠debugpy ãèªèãã¦ããã¾ãã1ã
% source ~/Developer/python/tutorial/.venv/bin/activate (.venv) % emacs &
使ãæ¹ã®è¦ç¹
M-x dape TAB TAB ã§ã³ãã³ãã®ä¸è¦§ãåºã¾ãã C-h f commandname ã§ã³ãã³ãã®èª¬æãåºã¾ãã REPL ã¦ã¤ã³ãã¦ã®éå§è¡ã«ã³ãã³ãã®ç°¡åãªèª¬æã表示ããã¾ãã
M-x | REPL | C-x C-a | 説æ |
---|---|---|---|
dape-info | i | Dape info ã¦ã¤ã³ãã¦ã表示/é表示 | |
dape-repl | R | REPL ã¦ã¤ã³ãã¦ã表示/ã«ç§»å |
ãã¬ã¼ã¯ãã¤ã³ã
ãã¬ã¼ã¯ãã¤ã³ãã¯ãã¤ã§ãã»ãã/ãªã»ããã§ãã¾ããã½ã¼ã¹ ãã¡ã¤ã«ã®å¯¾è±¡ã®è¡ã«ã«ã¼ã½ã«ããã£ã¦ãã C-x C-a b
ã¨ã¿ã¤ããã¾ããã¾ãã¯ãã¦ã¹ãæå¹ã®å ´åãã®è¡ã®å·¦ç«¯ã®ã¦ã¤ã³ãã¦ã®ã¸ãã§ã¯ãªãã¯ãã¾ããããã¨ãã®ããªã« â ãã¤ãã¾ãããªã C/C++ ã§ã¯ -g
ãªãã·ã§ã³ãä»ãã¦ã³ã³ãã¤ã«ãã¦ãããªãã¨ãã¬ã¼ã¯ãã¾ããã
M-x | REPL | C-x C-a | 説æ |
---|---|---|---|
dape-breakpoint-toggle | b | ãã¬ã¼ã¯ãã¤ã³ãã®è¨å®ã»åé¤ | |
dape-breakpoint-remove-all | B | ãã¹ã¦ã®ãã¬ã¼ã¯ãã¤ã³ãã®åé¤ | |
dape-breakpoint-hits | h | ããã ã«ã¦ã³ã ãã¬ã¼ã¯ãã¤ã³ã | |
dape-breakpoint-expression | e | æ¡ä»¶ã¤ããã¬ã¼ã¯ãã¤ã³ã | |
dape-breakpoint-log | l | (ä¸æã§ã¯ãªã) 該å½è¡ã§ã¡ãã»ã¼ã¸åºå |
ãããã° ã»ãã·ã§ã³
対象ã®ã½ã¼ã¹ ãã¡ã¤ã«ã®ã¦ã£ã³ãã¦ã§ M-x dape ã¾ã㯠C-x C-a d ãå
¥åããã¨ãã ãããã¡ã¼ã« Run adapter:
ã¨ããã³ãããåºã¾ãã <tab>/M-C-i ã«ããå¤æ° dape-configs
ã§å®ç¾©ããã¦ãããã®ã®ãã¡ã½ã¼ã¹ ãã¡ã¤ã«ã®ã¢ã¼ãã«ãããããè£å®åè£ã表示ããã¾ãããã¨ãã° codelldb 㨠lldb-dap ãé©åã«ã¤ã³ã¹ãã¼ã«ããã¦ã㦠C/C++ ã¢ã¼ãã§ãã¡ã¤ã«ãéãã¦ããã¨ãã¯
Click on a completion to select it. In this buffer, type RET to select the completion near point. 2 possible completions: codelldb-cc lldb-dap
ã®ããã«è¡¨ç¤ºããã¾ããå¤æ° dape-configs
ã®å
容ã¨èª¬æ㯠C-h v dape-configs ã§èªãã¾ãã python
ã python3
ã¸ã®ãªã³ã¯ã«ãªã£ã¦ããªãç°å¢ã§ã¯è£å®ãå¹ãã¾ããã debugpy command "python3" ã¨æ示çã«å
¥åããå¿
è¦ãããã¾ãã
å¿
è¦ã«å¿ããªãã·ã§ã³ãå
¥åãã¾ãããã¨ãã° C/C++ ã§ã³ã³ãã¤ã«ããããã¡ã¤ã«ãããã©ã«ãã® a.out
ããå¤æ´ãã¦ããå ´å㯠:program programname ã¨å
¥åãã¾ããã·ã³ããªã㯠ãªã³ã¯çµç±ã§éãã¦ããå ´å㯠prefix-local
/prefix-remote
ã調ç¯ããªãã¨ãã¬ã¼ã¯ãã¤ã³ãã§åæ¢ããªããã¨ãããã¾ãã debugpy
ã«å¯¾ãã¦ã¯ :justMyCode t
ã¨å
¥åããæ¹ãããããããã¾ãããã§ãªãã¨å®è¡ããããã° ã¢ã¸ã¥ã¼ã«ã«ã¾ã§ç«ã¡å
¥ãã¨ãã VS Code ã®ããã©ã«ãã¨ç°ãªãæåã«å½æããããããã¾ããã C-c C-k ã§å
é ã®ã³ã³ãã£ã°åã ããæ®ããªãã·ã§ã³ãã¯ãªã¢ã¼ãããã¨ãã§ãã¾ãã M-n/M-p ã§å
¥åå±¥æ´ããã©ãã¾ãã
å
é ã« :
ãã¤ããªãã·ã§ã³ã¯å DAP ã¢ããã¿ã¼ã«æ¸¡ããã®ã§ãã
- codelldb: Starting a New Debug Session
- lldb-dap: Configuration Settings Reference
- debugpy: Debug configuration settings
DAP ãããã¼ã®ãªãã·ã§ã³ã®å¤ã¯ json-parse-string 㧠Elisp ã®è¡¨ç¾ã«å¤æããå¿
è¦ãããã¾ãããã ã true
㯠t
ã false
㯠nil
ã§ãã
*scratch*
(json-parse-string "[null, \"log.txt\", null]") ;; C-j [:null "log.txt" :null]
M-x | REPL | C-x C-a | 説æ |
---|---|---|---|
dape | debug | d | ãããã°ã®éå§ (ãªãã·ã§ã³å ¥åãã) |
dape-restart | restart | r | ååã¨åããªãã·ã§ã³ã§éå§ |
dape-kill | kill | ãããã° ã»ãã·ã§ã³ã®å¼·å¶çµäº | |
dape-disconnect-quit | disconnect | D | ãããã°å¯¾è±¡ã®åä½ã¯ãã®ã¾ã¾ã¢ããã¿ã¼ãå¼·å¶çµäº |
dape-quit | quit | q | Dape ã®çµäº |
å®è¡å¶å¾¡
M-x | REPL | C-x C-a | 説æ |
---|---|---|---|
dape-pause | pause | p | å®è¡ã®ä¸æ |
dape-continue | continue | c | 次ã®ãã¬ã¼ã¯ãã¤ã³ãã¾ã§ç¶ç¶ |
dape-step-in | step | s | ã¹ãããå®è¡ |
dape-next | next | n | ãã¯ã¹ãå®è¡ (é¢æ°å é¨ã«ç«ã¡å ¥ããªã) |
dape-step-out | out | o | ç¾å¨ã®é¢æ°ãã return ããã¾ã§ç¶ç¶ |
dape-stack-select-up | up | < | é¢æ°å¼ã³åºãã®ãã¹ãã®ä¸ã«ç§»å |
dape-stack-select-down | down | > | é¢æ°å¼ã³åºãã®ãã¹ãã®ä¸ã«ç§»å |
dape-select-stack | S | é¢æ°å¼ã³åºãã®ãã¹ãã®é¸æ移å | |
dape-select-thread | t | ã¹ã¬ããã®é¸æ |
å¤ã®è¡¨ç¤º
M-x | REPL | C-x C-a | 説æ |
---|---|---|---|
dape-watch-dwim | w | ã¦ã©ããããå¤æ°ã®è¨å® | |
dape-read-memory | m | ã¡ã¢ãªã¼å 容ã®è¡¨ç¤º | |
dape-evaluate-expression | x | å¼ã®è©ä¾¡ |
è¨å®
Configuration ãåç §ãã¦ä¾¿å©ãããªãã®ãè¨å®ãã¾ãã
ã¢ããã¿ã¼ã®æ§æã®è¦å®å¤
M-x dape ã®ã¨ãã«ãã ãããã¡ã¼ã«å ¥åããã³ã³ãã£ã°ã®ããã©ã«ãå¤ãè¨å®ããæ¹æ³ã¯äºéãããã¾ãã
å¤æ° dape-configs
C-h v dape-configs ã§èª¬æã¨å
容ã表示ããã¾ããå
¨ä½ã¨ãã¦ã¯ alist (association list) ã¨ãããã¼ã¨å¤ã®çµã¿ã®ãªã¹ãã«ãªã£ã¦ãã¾ãããã¼ã¯ codelldb-cc
, debugpy
ãªã©ã®ã³ã³ãã£ã°åã§ããå¤ã¯ plist (property list) ã¨ããããããã£ã¼åã¨ããããã£ã¼å¤ã®çµã¿ã®ãªã¹ãã«ãªã£ã¦ãã¾ãã
ä¸è¨ã®è¨å®ã§ã¯ VS Code ã® The C/C++ extension ã®ããã©ã«ãã«ä¼¼ãã¦ãã¾ãã alist-get
㧠alist ã®å¤ (ããã§ã¯ plist) ãåå¾ã plist-put
ã§ããããã£ã¼åã¨ããããã£ã¼å¤ãã»ãããã¦ãã¾ãããã§ã«ååã®ããããã£ã¼ãåå¨ãã¦ããã¨ãã¯å¤ãæ´æ°ãããã§ãªãã¨ãã¯é
ç®ã追å ããã¾ãã
~/.emacs.d/init.el:
(use-package dape ;; ... :config ;; ... ;; Override the default configs. See `C-h v dape-configs`. (let ((program-file (lambda () (file-name-sans-extension buffer-file-name))) (compile-cmd (lambda () (concat "clang++ -std=c++17 -g -o " (file-name-sans-extension buffer-file-name) " " buffer-file-name))) (dape-config-put (lambda (config-name new-config) (let ((config (alist-get config-name dape-configs))) (cl-loop for (p v) on new-config by 'cddr do (plist-put config p v)))))) (funcall dape-config-put 'codelldb-cc (list 'compile compile-cmd :program program-file)) (funcall dape-config-put 'lldb-dap (list 'compile compile-cmd :program program-file)) (funcall dape-config-put 'debugpy (list :justMyCode t)))
let
ã§ãã¼ã«ã«å¤æ°ã« lambda
ã代å
¥ãã¦ããã®ã¯ Emacs ã»ãã·ã§ã³å
¨ä½ã«å®ç¾©ããããªãããã§ãã
å¤æ° dape-command
ããã¸ã§ã¯ãã®ã«ã¼ã ãã£ã¬ã¯ããªã¼ã« .dir-locals.el
ã¨ãããã¡ã¤ã«ãããããã§è¨å®ãã¾ããããã¸ã§ã¯ãé
ä¸ã«ã®ã¿æå¹ã§ãã
.dir-locals.el
((c++-mode . ((dape-command . (lldb-dap :program "helloworld")))))
è¨å®å¤ãããã°ã©ããã«ã«çæãããã¨ã㯠eval
ã使ãã¾ãã
.dir-locals.el
((c++-mode . ((eval . (setq-local dape-command `(lldb-dap :program ,(file-name-base buffer-file-name)))))))
ãã ã Emacs ãå®å
¨ã§ãªããããããªãæ¨ãåãåããã¦ãã¾ãã !
ã§çããã¨æ¬¡å以éã®åãåãããæå¶ã§ãã¾ãããã®ãã¨ã¯ ~/.emacs.d/init.el
ã«è¨é²ããã¾ãã
ä»é²: æ¨æºå ¥åºåãªãã¤ã¬ã¯ã·ã§ã³
codelldb
:stdio ["in.txt" :null :null]
lldb-dap
(lldb) settings list target.input-path target.input-path -- The file/path to be used by the executable program for reading its standard input. (lldb) settings list target.output-path target.output-path -- The file/path to be used by the executable program for writing its standard output. (lldb) settings list target.error-path target.error-path -- The file/path to be used by the executable program for writing its standard error.
:preRunCommands ["settings set target.input-path in.txt"]
debugpy
Command line arguments passed to the program. For string type arguments, it will pass through the shell as is, and therefore all shell variable expansions will apply. But for the array type, the values will be shell-escaped.
:args "arg1 arg2 arg3 <in.txt >out.txt 2>err.txt"