Автор: Михаил Глухов
Источник: http://axiger.livejournal.com/17393.html
Как подключать emacs к удаленному лисп-процессу через swank
Сначала цитата - вдруг кто-то не знает об этом замечательном инциденте.
И даже более впечатляющий пример удаленной отладки произошел в миссии NASA «Deep Space 1» в 1998 году. Через полгода после запуска космического корабля, небольшой код на Lisp должен был управлять космическим кораблем в течении двух дней для проведения серии экспериментов. Однако, неуловимое состояние гонки (race condition) в коде не было выявлено при тестировании на земле и было обнаружено уже в космосе. Когда ошибка была выявлена в космосе (100 миллионов миль от Земли) команда смогла произвести диагностику и исправление работающего кода, что позволило завершить эксперимент. Один из программистов сказал об этом следующее:
- Отладка программы, работающей на оборудовании стоимостью 100 миллионов долларов, которая находится в 100 миллионах миль от вас, является интересным опытом. REPL, работающий на космическом корабле, предоставляет бесценные возможности в нахождении и устранении проблем.
Лично я, смелый и храбрый программист могу только позавидовать такому экстремальному времяпрепровождению. И естественно, сразу как только я это прочел - мне захотелось попробовать так же :) Оказалось это довольно легко и может считаться штатной возможностью, которую следует юзать и в хвост и в гриву на боевых серваках (если конечно вы достаточно оптимистичны, самоуверенны и безрассудны :)
Я и не знал, что многие этого не знают, а те кто знают - забывают рассказать. Это как секс - после того как первый раз сделаешь это - начинаешь делать все на автомате, не задумываясь :)
Итак, по шагам:
- Заходим на сервак по ssh:
ssh user@host.ru
Спрашивают пароль, вводить нужно правильный, иначе странным образом ничего не получается. - Запускаем screen. По какой-то магической причине, если пропустить этот шаг, то после того как терминальная сессия закроется вся магия исчезнет.
- Внутри screen запускаем sbcl. Тут сразу дают REPL, но весь дзен будет дальше, поэтому...
- Вводим в REPL следующий код (можно скопировать прямо отсюда, вреда не будет, я гарантирую это!)
(require 'asdf)
Этот код запустить swank внутри sbcl и он (swank) начнет слушать 4005 порт, но будет делать это на удаленной машине - ну а мы там и находимся пока внутри терминальной сессии.
(asdf:oos 'asdf:load-op 'swank)
(setq swank:*use-dedicated-output-stream* nil)
(swank:create-server :coding-system "utf-8-unix" :dont-close t :port 4005) - Нажимаем Ctrl+a d - чтобы выйти из screen без его закрытия, оставив под screen`ом работающий sbcl с запущенным в нем swank`ом. Больше нам нечего делать в терминальной сессии, поэтому можно нажать Ctrl+d чтобы из нее выйти. Теперь мы снова у себя на машине.
- Открываем ssh-тоннель на удаленную машину:
Теперь все обращения к нашему 4005 порту будут уходить на удаленную машину и обращаться там по 4005 порту - а нам это и надоssh -2 -N -f -L 4005:localhost:4005 user@host.ru
- Заходим в emacs и набираем M-x slime-connect - и емакс послушно коннектится на локальный 4005 порт, который форвардится на удаленный 4005 порт, где его принимает swank, после чего вы можете наслаждаться мощью лиспа ни в чем себе не отказывая.
Что может быть полезным:
- swank сам по себе - это библиотка лиспа. Она может быть неустановлена. Установиить можно например с помощью asdf-install, например так
(require 'asdf-install)
Но лучше бы вам знать, как устанавливать библиотки в лиспе вручную. Все просто - нужно слить библиотеку, положить ее в нужную папку (у меня это /usr/lib/sbcl/site/) и сделать симлинк на asd-файл в папке систем (у меня это /usr/lib/sbcl/site-systems/). Нужные папки легко найти по команде locate site-systems - там оно все рядом. Альтернативный вариант поиска, если вы знаете какую-нибудь из установленных библиотек, например alexandria - это выполнить в REPL такой код:
(asdf-install:install 'swank)(asdf:component-pathname (asdf:find-system '#:alexandria))
- версия swank (снапшот) должна быть идентична и на клиенте и на сервере. Если об этом забыть можно словить прикольные глюки :)
- Если, когда вы отошли хакнуть что-нибудь другое или просто попить кофе, ssh-тоннель умирает от безделья и вам приходится с матом поднимать его снова, то пропишите в /etc/ssh/ssh_config директиву
ServerAliveInterval 5
- Некоторые лисперы забывают сконфигурировать emacs :) В вашем инициализационном файле емакса должно быть что-то похожее на это:
;; Lisp (SLIME) interaction
(setq inferior-lisp-program "sbcl"
lisp-indent-function 'common-lisp-indent-function
slime-complete-symbol-function 'slime-fuzzy-complete-symbol
; common-lisp-hyperspec-root "file:///Users/lisp/HyperSpec"
slime-startup-animation nil)
;; SLIME
(add-to-list 'load-path "~/.emacs.d/slime")
(require 'slime)
;(set-language-environment "utf-8")
(setq slime-net-coding-system 'utf-8-unix)
(slime-setup '(slime-fancy))
Это не единственно-верный способ работать с лиспом удаленно. Но я им пользуюсь и нахваливаю. Ссылки на другие способы приветствуются