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

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

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

99%の場合、これはうまく機能しますが、時には次のメッセージが表示されます。

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

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

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


編集する:私のもの.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

答え1

私もあなたのような問題があるかどうかはわかりませんが、ネットワークが予期せずダウンするたびに同様の画面動作が表示されることがあります。

しばらくすると(約10〜15分)、画面が再びアクティブになり、接続が再接続されることがあります。いくつかの調査の最後に、マニュアルページで小さなメモを見つけました。

   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.

リンク解除後の画面の停止についてGoogleが提供した唯一のページであるため、誰かに役立ちます。

答え2

最後に、画面に接続したシェルの擬似端末を待つと、画面セッションが中断されることがあります。場合によっては、接続が失われるとシェルが終了し、画面が切り離される前に画面がタイムアウトする必要があります。

を実行すると、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を終了すると、画面セッションが解放され、再接続することができる。

答え3

この画面セッションが開始されてから画面がアップグレードされましたか?

覚えていません。精密詳細ですが、1〜2ヶ月前に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

関連情報