33 votes

Impossible d'arrêter WEBrick 1.3.1 avec ctrl-c sur Ubuntu 11.04

Je suis l'aide de RVM, Ruby 1.9.2, et les Rails 3.0.7

Un standard de tuer le processus à partir d'un autre terminal ne fonctionne pas, soit, mais kill -9, bien sûr.

J'ai trouvé une question similaire, CTRL+C pour Webbrick serveur ignoré, mais il est difficile de savoir si cette question est de décrire le même problème sous-jacent. Aussi, la résolution ne semble pas s'appliquer, car je ne suis pas en utilisant :git dans mon Gemfile.

mise à jour 1: (vieux maintenant... voir la mise à jour 2, ci-dessous, pour le vrai scoop)

J'ai réussi à réduire le problème à un seul bijou. Si vous source le script de test suivant, vous pouvez voir le problème, trop (en supposant que vous êtes sur Ubuntu 11.04... il n'y a pas de problème dans 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

Le fait que le problème est causé par les Rails' interaction avec un bijou m'amène à me croient maintenant que cette question est liée à CTRL+C pour Webbrick serveur ignoré, bien que le cas de test ci-dessus montre que celui-ci est clairement pas causés par l'utilisation d' :git pour un bijou.

mise à jour 2:

Dans la mise à jour 1 , j'ai mentionné que j'ai rétréci vers le bas à un joyau. Quand je suis allé à travers ce bijou, j'ai fini par trouver le vrai coupable. Le gem a été faire un seul appel système. J'ai fait une très légère modification dans le script de test où je n'ai plus de charge, le barista gem, mais plutôt j'ai tout simplement ajouter un seul appel système à la fin de l'application.rb. Avec ce système d'appel, ctrl-c ne fonctionne pas. Supprimer l'appel système et fonctionne bien.

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

Cela pourrait expliquer l'apparente similitude entre cette question et CTRL+C pour Webbrick serveur ignoré. Mon intuition est que le gem ils mentionnent également fait un appel système.

18voto

StrangeElement Points 1632

Je préfère de commentaires que d'ajouter une réponse, mais pas assez de rep.

J'ai le même problème et a trouvé que la reprise (avec fg) après tapant ctrl-c puis, s'arrêtant (avec ctrl-z, tel que proposé ci-dessus) fait le tour.

La recette est donc:

  1. ctrl-c (ne fait rien tout de suite)
  2. ctrl-z (pauses WEBrick, remonte à la coque)
  3. fg (cvs WEBrick, immédiatement suivi par le biais d'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, 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
    

8voto

Jamie Penney Points 2821

J'ai un problème similaire, j'utilise Ctrl-Z pour mettre le travail en pause, puis kill -9 %1 pour supprimer le premier travail en pause. Une façon détournée de le tuer, mais ça marche.

Consultez cette question sur Superuser pour plus d'informations: http://superuser.com/questions/243460/what-to-do-when-ct-r-ct-cen-cant-kill-a-process

6voto

sarnold Points 62720

Je crois ^C ne peut pas tuer WEBrick serveurs, car le serveur crée une nouvelle session:

En 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

(Très semblable code existe en rack/server.rb, donc si vous êtes de départ WEBrick par rack, vous voudrez peut-être laisser hors de l' -D ou --daemonize options de ligne de commande.)

Et à partir de l' setsid(2) man:

   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.

n'a pas de contrôle ats signifie que les signaux générés par un terminal (^Z SIGTSTP, ^\ SIGKILL, SIGTTIN, SIGTTOU, etc.) ne peut pas atteindre le processus, même si elle avait été commencé sur le terminal. Le lien a été rompu.

6voto

Gordon McCreight Points 698

Ok, le problème a été résolu pour moi. Une récente mise à jour du noyau, auquel j'avais postulé dans le cadre de Ubuntu standard mises à jour, le problème a été résolu.

Aussi, voici une bonne discussion de la question, ce qui explique que la cause était un noyau de régression introduite dans 2.6.38 ( http://redmine.ruby-lang.org/issues/4777 )

La régression a été patché, et il semble que le patch récemment dans Ubuntu mises à jour, donc si vous êtes être affecté par ce problème, vous devez appliquer les dernières mises à jour.

4voto

Kelvin Points 5810

C'est aussi se passe pour moi sur Mac OS X.

Étonnamment, ni Rack ou WEBrick est mise place des gestionnaires de signaux. J'ai mis cela dans mon rack application de l' call méthode et il me dit que l' DEFAULT gestionnaire pour SIGINT est l'actuel (retourne la Chaîne de caractères "DEFAULT"):

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

Je soupçonne que quelque chose se passe dans ruby select c'est le piégeage des signaux.

Voici 2 façons d'arrêter le serveur:

1) Appuyez sur les touches ctrl-z pour suspendre. Ensuite, kill -ABRT pid_or_job_id. Je ne sais pas comment "proprement" le processus s'arrête si. C'est gênant, mais vous n'avez pas à ajouter du code.

2a) Si vous utilisez un Rack, ajouter ce droit avant vous appelez Rack::Handler::WEBrick.run:

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

2b) Si vous utilisez de la vanille WEBrick:

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

server votre WEBrick objet serveur.

Ceux-ci sont bons si vous allez être en utilisant SIGINT souvent. Vous pouvez ajouter des gestionnaires d' TERM et HUP également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X