33

I'm using RVM, Ruby 1.9.2, and Rails 3.0.7

A standard kill of the process from another terminal doesn't work, either, but kill -9 does, of course.

I found a similar question, CTRL+C to Webbrick server ignored, but it's unclear whether that question is describing the same underlying issue. Also, the resolution doesn't seem to apply, since I'm not using :git in my Gemfile.

update 1: (old now... see update 2, below, for the real scoop)

I managed to narrow the issue down to a single gem. If you source the following test script, you can see the issue, too (assuming you're on Ubuntu 11.04... there was no issue in 10.04)

rm -rf tmpkilltest

rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest

gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri

rails new tmpkilltest

cd tmpkilltest

echo "gem 'barista', '1.0'" >> Gemfile

bundle

rails s

The fact that the issue is caused by Rails' interaction with a gem leads me to now believe that this question actually is related to CTRL+C to Webbrick server ignored, though the test case above shows that this one is clearly not caused by using :git for a gem.

update 2:

In update 1 I mentioned that I narrowed it down to a gem. When I went through that gem, I eventually found the real culprit. The gem was making a single system call. I've made a very minor modification to the test script where I no longer load the barista gem, but rather I simply append a single system call at the end of the application.rb. With that system call, ctrl-c doesn't work. Remove the system call and it does work.

rm -rf tmpkilltest

rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest

gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri

rails new tmpkilltest

cd tmpkilltest

bundle

echo "\`date\`" >> config/application.rb

rails s

This could explain the seeming similarity between this question and CTRL+C to Webbrick server ignored. My hunch is that the gem they mention also makes a system call.

Community
  • 1
  • 1
Gordon McCreight
  • 2,579
  • 1
  • 22
  • 15
  • 1
    I do have exactly the same issue with ruby 1.9.2 and ubuntu 11.04, it's really annyoing. Please keep me informed about possible solutions :) – gucki May 09 '11 at 09:35
  • 1
    http://rails.lighthouseapp.com/projects/8994/tickets/6760-very-obscure-issue-with-ctrl-c-in-console-not-workng-and-periodic-freezes – gucki May 09 '11 at 09:38
  • 1
    http://redmine.ruby-lang.org/issues/4608 – gucki May 09 '11 at 09:44
  • Could you could accept an answer? It doesn't have to be mine, but that would be nice :-P – Jamie Penney May 11 '11 at 01:08
  • That's a good question, and one I don't know the answer to. I would generally accept a workaround as an answer if there is no actual solution to be had. I guess part of the usefulness of SO is to make it easier to solve problems via Google, so for the majority of people who don't actually work on Webrick a workaround is probably just fine. Anything more than that probably belongs on the Webrick bug tracker (or whatever is the problematic component). – Jamie Penney May 15 '11 at 22:55
  • I like @StrangeElement's solution. `Ctrl + C`, `Ctrl + Z`, then `fg`. Would be great if a real solution was found but in the meantime I'm going to adopt that as my workaround. – Tass May 24 '11 at 19:24
  • Fair enough, Jamie. A real answer doesn't appear to be forthcoming, so I'll choose yours since it's the workaround I've been using. That said, I'll change the accepted answer if someone comes along with the real deal. – Gordon McCreight Jun 05 '11 at 05:33
  • Another Ruby red mine ticket, http://bugs.ruby-lang.org/issues/4777, says it's a kernel (Linux) bug. They give a work around (essentially equivalent to the Ctrl-C/Ctrl-Z one, for use if you've demonized the server: kill -INT $( – jackr Jun 12 '12 at 02:21
  • If you'd like the "nuke from orbit" solution, it goes a little like this... `killall -9 ruby`. Disclaimer: There may be unexpected results of other processes closing. – AJFaraday Nov 29 '17 at 11:13

13 Answers13

18

I'd rather comment than add an answer for this, but not enough rep.

I have the same issue and found that resuming (with fg) after typing ctrl-c then pausing (with ctrl-z, as offered above) does the trick.

So the recipe is:

  1. ctrl-c (does nothing right away)
  2. ctrl-z (pauses WEBrick, goes back to shell)
  3. fg (resumes WEBrick, immediately follow through with SIGINT)

    lampadmin@lampadmin-DX4840:/var/www/rails/agences$ r s
    => Booting WEBrick
    => Rails 3.0.5 application starting in development on http://0.0.0.0:3000
    => Call with -d to detach
    => Ctrl-C to shutdown server
    [2011-05-14 14:25:36] INFO  WEBrick 1.3.1
    [2011-05-14 14:25:36] INFO  ruby 1.9.2 (2011-02-18) [x86_64-linux]
    [2011-05-14 14:25:36] INFO  WEBrick::HTTPServer#start: pid=2585 port=3000
    

    ^C^Z (<-- ctrl-c, then ctrl-z)

    [1]+  Stopped                 rails s
    lampadmin@lampadmin-DX4840:/var/www/rails/agences$ fg
    rails s
    [2011-05-14 14:25:45] INFO  going to shutdown ...
    [2011-05-14 14:25:45] INFO  WEBrick::HTTPServer#start done.
    Exiting
    
Nicholas Riley
  • 43,532
  • 6
  • 101
  • 124
StrangeElement
  • 2,282
  • 2
  • 16
  • 20
8

I'm having a similar problem, have been using Ctrl+Z to pause the job, then kill -9 %1 to kill the first paused job. Roundabout way of killing it, but it works.

See this question on Superuser for more info: https://superuser.com/questions/243460/what-to-do-when-ctrl-c-cant-kill-a-process

Mwiza
  • 7,780
  • 3
  • 46
  • 42
Jamie Penney
  • 9,424
  • 3
  • 29
  • 37
6

I believe ^C can't kill WEBrick servers because the server creates a new session:

In webrick/server.rb:

  class Daemon
    def Daemon.start
      exit!(0) if fork
      Process::setsid
      exit!(0) if fork
      Dir::chdir("/")
      File::umask(0)
      STDIN.reopen("/dev/null")
      STDOUT.reopen("/dev/null", "w")
      STDERR.reopen("/dev/null", "w")
      yield if block_given?
    end
  end

(Very similar code exists in rack/server.rb, so if you're starting WEBrick via rack, you might want to leave off the -D or --daemonize command line options.)

And from the setsid(2) manpage:

   setsid() creates a new session if the calling process is not
   a process group leader.  The calling process is the leader of
   the new session, the process group leader of the new process
   group, and has no controlling tty.

has no controlling tty means that signals generated by a terminal (^Z SIGTSTP, ^\ SIGKILL, SIGTTIN, SIGTTOU, etc.) can't reach the process even if it had been started on that terminal. The link has been severed.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • I was able to kill it in a separate terminal, but only by using -9. To my mind that means that it's likely that SIGINT was being delivered to the process when I hit ctrl-c, but the the process was ignoring it (just like it was ignoring the explicit kill in the other terminal until I forced it with the -9) – Gordon McCreight May 05 '11 at 05:42
  • I'm not sure I understand what you're saying. I'm also having the same issue, `ctrl + c` used to work well in 10.04 and now I'm finding it works intermittently in 11.04. – Tass May 24 '11 at 19:15
  • If you look at webrick.rb, it says: "To start a WEBrick server as a daemon simple run WEBrick::Daemon.start". I grepped the webrick code and I don't see it starting a daemon by default. Good try, but this doesn't apply to the usual case. – Kelvin Nov 13 '12 at 23:39
6

Ok, the issue has been resolved for me. A recent kernel update, which I applied as part of Ubuntu's standard updates, fixed the problem.

Also, here is a good discussion of the issue, which explains that the root cause was a kernel regression introduced in 2.6.38 ( http://redmine.ruby-lang.org/issues/4777 )

The regression was patched, and it looks like the patch recently made it into Ubuntu's updates, so if you're being affected by this issue, you should apply the latest updates.

Gordon McCreight
  • 2,579
  • 1
  • 22
  • 15
4

This is also happening for me on Mac OS X.

Surprisingly, neither Rack or WEBrick is setting up custom signal handlers. I put this in my rack app's call method and it's telling me that the DEFAULT handler for SIGINT is the current one (returns the String "DEFAULT"):

p Signal.trap('INT', 'DEFAULT')

I suspect that something's going on in ruby's select that's trapping the signals.

Here's are 2 ways to stop it the server:

1) Press ctrl-z to suspend. Then kill -ABRT pid_or_job_id. I don't know how "cleanly" the process exits though. This is annoying but you don't have to add any code.

2a) If you're using Rack, add this right before you call Rack::Handler::WEBrick.run:

Signal.trap('INT') {
  Rack::Handler::WEBrick.shutdown
}

2b) If you're using vanilla WEBrick:

Signal.trap('INT') { server.shutdown }

where server is your WEBrick server object.

These are good if you're going to be using SIGINT often. You may want to add handlers for TERM and HUP also.

Kelvin
  • 20,119
  • 3
  • 60
  • 68
1

I had the same problem when updating my Ubuntu. Impossible to quit normally webrick using Ctrl+C, had to use kill -9...

Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
Nicolas Blanco
  • 11,164
  • 7
  • 38
  • 49
1

I ran into this problem myself. I am using rvm rails 3.0.9 and ubuntu 11.04 32bit running unity. I found that terminator will pass the Ctrl+c to rails.

Mwiza
  • 7,780
  • 3
  • 46
  • 42
alley
  • 11
  • 1
1

used this line to create shortcut with ccsm (compiz conig settings manager or smth like this) -> commands:

kill -9 `pgrep -fl 'script/rails s' | awk '{print $1}'`

set to (ctrl+shift+`) or anything you like

closedmind
  • 11
  • 2
0

If ctr+c is not working, then before going to implement the methods mentioned , just see your terminal settings. Sometimes it may happen that we change the shortcut keys of terminal as our convenience. And we assign ctr+c for copying content of terminal. In this case ctr+c wont work for stopping the server, instead it will be used as copy purpose.

If the settings are not changed then try using another port like 4000.

Ruturaj Bisure
  • 151
  • 1
  • 13
0

Seems to be a problem with Unity and Terminal the ^c is not processed correctly for some reason. try doing the same thing using terminator (a better terminal). Or just use gnome.

At least this is how I resolved the problem. I propose we move this to askubuntu.com.

In U10.04 I had this problem running webrick, mongrel, console, sqlite, it didn't matter what I ran actually.

Dmitriy Likhten
  • 5,076
  • 7
  • 36
  • 47
  • I just logged in using "ubuntu classic no effects" (gnome without Unity) and ran the test script listed in "Update 2" in both the regular terminal and terminator. It continued to exhibit the same bad behavior. Note that a normal kill (without the -9) also doesn't work, so it's not that the signal isn't getting passed because of some bad interaction between the gui components. Also, ctrl-c works just fine if no system call is made. (see update 2) – Gordon McCreight May 24 '11 at 20:53
  • Unless you NEED webrick, why not just intall mongrel `gem install mongrel` or put it in the bundler dependency and never worry about it again. – Dmitriy Likhten May 24 '11 at 23:03
  • That's actually a great idea, but I just checked, and problem doesn't go away when using mongrel. – Gordon McCreight May 24 '11 at 23:55
  • @Gordon have you tried other terminal programs? Something is wrong with the default one. – Dmitriy Likhten May 25 '11 at 01:47
  • terminator exhibits the same problem for me. Given that delivering SIGINT via kill doesn't work either, I highly doubt that an alternative terminal is going to fix the problem for anyone. – Bryan Larsen Jun 30 '11 at 19:42
0

Interesting experience (and good workaround for the next weeks):

If you are under Ubuntu and use Guake for quick terminal access, you can launch

rails s

there. Ctrl + C reproducibly works there for me and stops the server.

Hope I could help! :)

EDIT: As obviously this is not reproducibly for everyone, here is my setup: Ubuntu 11.04, 32-bit, Guake 0.4.2-4ubuntu1

Mwiza
  • 7,780
  • 3
  • 46
  • 42
Dorian
  • 11
  • 2
  • Thanks for the answer, Dorian. Guake doesn't seem to make a difference on my setup (and I'm positive it is not a terminal emulator issue since you can't "kill" the process from other places, except with a -9). That said, I've had fun playing with Guake... cool term! – Gordon McCreight Jun 03 '11 at 18:03
  • Hi Gordon, that's a pitty, I'm curious what could be the difference between our systems? – Dorian Jun 05 '11 at 21:28
0

My last answer was deleted don't know why but i try again cause i really think this is very related with the issue.

In my Gemfile I have only one gem which is using the argument :git.

gem 'rails_admin', :git => 'git://github.com/sferik/rails_admin.git'

I have the same issue af all of you, ctrl+C is ignored; but if i delete this gem dependency, (and I delete de related initializer) the issue is gone and i can use ctrl+c as before.

I could think it is a bug related with rails_admin gem but as I read in this other question: CTRL+C to Webbrick server ignored its more likely to be related with any gem in which the :git parameter is used...

Hope its helpful.

Community
  • 1
  • 1
diegopau
  • 1,324
  • 10
  • 22
0

Found some kind of solution. Run in terminal:

stty -echoctl

And then Ctrl-C will work. http://linux.m2osw.com/remove-ctrl-C-from-being-printed-in-console

Worked just for one session. Posted better solution near.

closedmind
  • 11
  • 2