web-dev-qa-db-ja.com

GNU再接続しようとすると画面がフリーズする

いくつかの長時間実行中のGNUスクリーンセッションがあります。それらが実行されているボックスにsshし、screen -d -r fooを実行して、他の場所に接続されている場合はそれらを切り離してからアタッチします。私の現在のウィンドウでそれら。

これは99%の確率で正常に機能しますが、場合によっては次のようになります。

$ screen -d -r foo
[2430.foo detached.]

...そして何も起こりません。シェルに戻ることができません。別のウィンドウで試しても同じことができます。私ができる唯一のことは、そのスクリーンセッションを破棄し(そのウィンドウで実行されていたすべてのプログラムを失います)、それを再作成することです。

なぜこれが起こるのですか?それを回避したり、発生した場合に正常に再接続するにはどうすればよいですか?


編集:My .screenrc

startup_message off
defwritelock off
bind q quit
caption always '%{gk}   (%n) %t                   %{y}%d %M %Y :: %c:%s                   %{b}%W%{d}'
screen -t ZSH
autodetach on
shelltitle ZSH
defutf8 on

編集:添付しようとしたときのstraceログの終わり:

readlink("/proc/self/fd/0", "/dev/pts/14", 4095) = 11
stat64("/dev/pts/14", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
stat64("/dev/pts/14", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/dev/pts/14", O_RDWR|O_NONBLOCK)  = 3
geteuid32()                             = 1000
getegid32()                             = 1000
close(3)                                = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
umask(0)                                = 022
lstat64("/var/run/screen", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
access("/var/run/screen/S-mrozekma", F_OK) = 0
stat64("/var/run/screen/S-mrozekma", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
umask(022)                              = 0
uname({sys="Linux", node="etudes-2", ...}) = 0
rt_sigaction(SIGHUP, {0x806e520, [], 0}, {SIG_DFL, [], 0}, 8) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/var/run/screen/S-mrozekma", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 6 entries */, 32768)     = 124
stat64("/var/run/screen/S-mrozekma/2386.chat", {st_mode=S_IFIFO|0700, st_size=0, ...}) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/var/run/screen/S-mrozekma/2386.chat", O_WRONLY|O_NONBLOCK) = 4
geteuid32()                             = 1000
getegid32()                             = 1000
fcntl64(4, F_SETFL, O_RDONLY)           = 0
geteuid32()                             = 1000
getegid32()                             = 1000
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
geteuid32()                             = 1000
getegid32()                             = 1000
setuid32(1000)                          = 0
setgid32(1000)                          = 0
stat64("/var/run/screen/S-mrozekma/2386.chat", {st_mode=S_IFIFO|0700, st_size=0, ...}) = 0
getpid()                                = 30081
write(4, "\0gsm\4\0\0\0/dev/pts/14\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 12336
16
Michael Mrozek

私があなたと同じ問題を抱えていたかどうかはわかりませんが、ネットワークが誤って切断されるたびに、同じような画面の動作をすることがあります。

しばらくすると(約10〜15分)、画面に再び接続できます。調査の結果、manページに小さなメモが見つかりました。

   nonblock [on|off|numsecs]

   Tell  screen  how to deal with user interfaces (displays) that cease to
   accept output. This can happen if a user presses ^S or a TCP/modem con‐
   nection gets cut but no hangup is received. If nonblock is off (this is
   the default) screen waits until the display restarts to accept the out‐
   put.  If  nonblock is on, screen waits until the timeout is reached (on
   is treated as 1s). If the display  still  doesn't  receive  characters,
   screen will consider it "blocked" and stop sending characters to it. If
   at some time it restarts to accept characters, screen will unblock  the
   display and redisplay the updated window contents.

それは誰かを助けるかもしれません、これはグーグルが私に教えてくれた後の画面のフリーズについての唯一のページですので、.

8
rush

スクリーンセッションは、最後にスクリーンに接続したシェルの疑似ターミナルを待ってハングしている可能性があります。ときどき接続が失われるとシェルが離れ、画面から切り離すために画面がタイムアウトする必要があります。

ls -l /proc/<screen_pid>/fd/<descriptor_of_hung_write>を実行すると、前のシェルセッションのptsであることがわかります。

アタッチしていたbash/Shellセッションを終了すると、再度アタッチできるようになります。

# ps auwxf|grep -B2 screen
root     23214  0.0  0.0 109304  4016 ?        Ssl  19:13   0:00  \_ sshd: root@pts/6 
root     23566  0.0  0.0 117400  2272 pts/6    Ss   19:13   0:00      \_ -bash
root     10445  0.0  0.0 125156  1156 pts/6    S+   19:23   0:00          \_ screen -ADR MYSCREEN

この場合、プロセス23214を強制終了すると、スクリーンセッションが解放され、再接続できます。

6
ZachL

スクリーンセッションが開始されてからスクリーンはアップグレードされましたか?

exactの詳細を思い出すことはできませんが、約1か月前、apt-get dist-upgrade(debian sidへ)システムでアップグレードされた画面とpostinstは互換性のないアップグレードについて警告しました。古いセッションの再接続を可能にするために、古い画面のコピーが(/ tmp IIRCの下のどこかに)保持されていましたが、それらを強制終了して再起動することをお勧めしました。

あなたが報告する症状は、私が誤って新しい/ usr/bin/screenを使用して古い画面セッションに再接続しようとしたときに見たものに似ています。

6月に戻ったdpkg.logから、これはおそらくこれでした:

2012-06-14 08:11:51 upgrade screen:AMD64 4.0.3-14 4.1.0~20120320gitdb59704-2

4
cas