Ekran GNU zawiesza się podczas próby ponownego podłączenia

16

Mam kilka długich sesji ekranowych GNU. Piszę do skrzynki, na której są uruchomione, i biegam, screen -d -r fooaby je odłączyć, jeśli są połączone gdziekolwiek indziej, a następnie dołączyć je w moim bieżącym oknie.

W 99% przypadków działa to dobrze, ale czasami dostaję to:

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

... i nic się nie dzieje; W ogóle nie mogę wrócić do muszli. Próbowanie w innym oknie robi to samo, jedyne, co mogę zrobić, to zniszczyć tę sesję ekranu (tracąc wszystkie uruchomione w niej programy) i odtworzyć ją

Dlaczego to się dzieje? Jak mogę tego uniknąć lub pomyślnie połączyć się ponownie, kiedy to się stanie?


Edycja : Mój .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

Edycja : koniec stracedziennika podczas próby dołączenia:

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
Michał Mrożek
źródło
opublikowanie ~ / .screenrc (i może / etc / screenrc, jeśli jest dostosowany) może być pomocne
user2387,
Proszę zamieścić dane wyjściowe strace screen -d -r foo(być może konieczne będzie wykonanie nie ustawionej kopii [ug] id screenpliku wykonywalnego) i strace -p$(pidof SCREEN)mniej więcej w czasie nieudanego ponownego połączenia.
Gilles „SO- przestań być zły”
@Gilles To się po prostu powtórzyło; Dodałem stracedziennik. straceProces głównego ekranu pokazuje podobny blok w write()rozmowie
Michael Mrozek
Wydaje się, że dzieje się tak, gdy poprzednio podłączony ekran nie został prawidłowo odłączony (w tym przypadku miałem go podłączony z innego komputera, który następnie utracił połączenie sieciowe). Może screenpróbujesz zapisać połączenie, które już nie istnieje?
Michael Mrozek
Czy proces głównego ekranu (ten nazywany SCREEN) jest nadal aktywny? Co on robi ( strace)?
Gilles „SO- przestań być zły”

Odpowiedzi:

8

Nie jestem pewien, czy miałem ten sam problem co ty, ale czasami mam podobne zachowanie ekranu za każdym razem, gdy moja sieć została przypadkowo odłączona.

Po chwili (około 10-15 minut) ekran jest ponownie dostępny do ponownego połączenia. Po kilku dochodzeniach znalazłem małą notatkę na stronie podręcznika:

   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.

Może to komuś pomoże, bo to jedyna strona o zawieszeniu ekranu po tym, jak dała mi go niezadowolenie.

wysypka
źródło
Nie do końca rozumiem, na podstawie tego wpisu strony podręcznika, ale to naprawiło to dla mnie. Ustawiłem się nonblock 5jakiś czas temu i po prostu znów natknąłem się na problem, a po 5 sekundach nagle przyłączyłem się normalnie
Michael Mrozek
6

Sesja ekranowa prawdopodobnie została zawieszona w oczekiwaniu na pseudo-terminal powłoki, którą ostatnio podłączono do ekranu. Czasami utracone połączenie pozostawia tę powłokę i ekran musi przekroczyć limit czasu, aby się od niego odłączyć.

Jeśli uruchomisz ls -l /proc/<screen_pid>/fd/<descriptor_of_hung_write>, powinieneś zobaczyć, że jest to punkt dla poprzedniej sesji powłoki.

Po zabiciu sesji bash / shell, z którą się przyłączyłeś, będziesz mógł ponownie dołączyć.

# 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

W takim przypadku proces zabijania 23214 spowoduje zwolnienie sesji ekranowej i będzie można ponownie dołączyć.

ZachL
źródło
3
Co powinienem zrobić, jeśli nie ma procesu nadrzędnego?
d33tah
Ten pomógł mi dzisiaj, zabicie sshd sprawiło, że ekran ponownie zareagował! Oszczędność godzin i godzin pracy!
user230910,
4

Czy ekran został zaktualizowany od czasu rozpoczęcia tych sesji ekranowych?

Nie pamiętam dokładnych szczegółów, ale pamiętam, że mniej więcej miesiąc lub trzy lata temu apt-get dist-upgrade(do Debiana Sid) zaktualizowałem ekran w moim systemie, a postinst ostrzegł mnie przed niekompatybilnym uaktualnieniem. Kopia starego ekranu została zachowana (gdzieś w / tmp IIRC), aby umożliwić ponowne dołączanie do starych sesji, ale zalecane było zabicie ich i ponowne uruchomienie.

Zgłaszane symptomy brzmią podobnie do tego, co widziałem, gdy przypadkowo próbowałem ponownie połączyć się ze starą sesją ekranową z nowym / usr / bin / screen.

Możliwe, że to z dpkg.log w czerwcu:

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

cas
źródło
Ten problem został rozwiązany przed wydaniem Debian 7 Wheezy. Jest jednak obecny w odpowiednich wcześniejszych wersjach lub migawkach git. Patrz: bugs.debian.org/683228
Axel Beckert,
To właśnie mi się dzisiaj przydarzyło na starszej instalacji Centos 6. Dzięki!
Mike Andrews,
Właśnie mnie to ugryzło w Gentoo, aktualizowałem z 4.3 do 4.4.
jlh