jsk-ros-pkg / euslime

Emacs SLIME for Euslisp
BSD 3-Clause "New" or "Revised" License
7 stars 3 forks source link

Crashes after C-c on stagnated ros::roseus #7

Open YUKINA-3252 opened 2 years ago

YUKINA-3252 commented 2 years ago

Describe the bug Emacs crashes

To Reproduce without a proper master:

  1. (robot-init)
  2. C-c C-c

Log *slime-events*

(:emacs-rex
 (swank-repl:listener-eval "(baxter-init)\n")
 "USER" :repl-thread 44)
(:write-string "^[[31m[ERROR] [1650021924.495021658]: [registerPublisher] Failed to contact master at [localhost:11311].  Retrying...^[[\
0m\n")
(:emacs-interrupt :repl-thread)
(:emacs-rex
 (swank:set-package "")
 "USER" :repl-thread 45)

Log *inferior-lisp*

[DEBUG - protocol:L69] Processing id: 44 ...
[INFO - protocol:L71] func: swank_repl_listener_eval
[INFO - protocol:L72] args: [u'(baxter-init)\n']
[DEBUG - handler:L216] Acquiring lock: <thread.lock object at 0x7f996c698590>
[INFO - bridge:L371] eval: (baxter-init)

[DEBUG - server:L45] output: [ERROR] [1650021924.495021658]: [registerPublisher] Failed to contact master at [localhost:11311].  Retrying...

[DEBUG - server:L80] raw header: 000020
[DEBUG - server:L87] raw data: (:emacs-interrupt :repl-thread)

[INFO - protocol:L71] func: _emacs_interrupt
[INFO - protocol:L72] args: [Symbol(u':repl-thread')]
[DEBUG - server:L80] raw header: 00003b
[DEBUG - server:L87] raw data: (:emacs-rex (swank:set-package "") "USER" :repl-thread 45)

[DEBUG - protocol:L69] Processing id: 45 ...
[INFO - protocol:L71] func: swank_set_package
[INFO - protocol:L72] args: [u'']
[DEBUG - handler:L611] Acquiring lock: <thread.lock object at 0x7f996c698590>

Process inferior-lisp terminated
Affonso-Gui commented 2 years ago

Why it crashes:

  1. While ros::roseus is trying to connect with the master, the eus node is not responsive to C-c interruptions. This is because the eus sigint handler will only set a flag on C-c, and then activate the new prompt on calls to breakck. In time-extensive operations we would usually set a smaller timeout, and loop for trials and breakcks. However, ros::init doesn't appear to have a timeout option. A solution for this would be to register separate sigint handlers during and after the master connection, but I am not sure if the ability to interrupt a ros::roseus call is worth the changes. https://github.com/jsk-ros-pkg/jsk_roseus/blob/master/roseus/roseus.cpp#L655 http://wiki.ros.org/roscpp/Overview/Initialization%20and%20Shutdown

  2. Meanwhile, the emacs client in euslime sends an sigint to the euslisp process and assumes that the process is responsive. Trying to evaluate another request during this time will force the emacs buffer into waiting a response from the euslisp process, which in this case won't come until successfully connected to the master. Thus, leading to a crash.

I'll take a look if there is a way for the emacs client to assert if the console is responsive or not before sending requests.

Affonso-Gui commented 2 years ago

I have added a 0.5s timeout to interruption requests in https://github.com/jsk-ros-pkg/euslime/commit/8098612ad8ed8e7abca4375a247f1b4de88fa357 This way the emacs window will not crash even if the emacs process is not responsive.