LINUX.ORG.RU

Как восстановить ввод/вывод дочернего процесса?

 , , , ,


0

1

Если управляющий терминал отвалился к примеру. Запустил я что-то, затем fork()нул и закрыл эмулятор терминала. Дочка демонизирована от слова совсем.

Водно что пайп умер

 dron@gnu:~$ strace -p 382320
 strace: Process 382320 attached
 restart_syscall(<... resuming interrupted read ...>) = 0
 pipe2([3, 4], O_CLOEXEC)                = 0
 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, 
 rlim_max=1024*1024}) = 0
 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, 
 rlim_max=1024*1024}) = 0
 mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fa450de8000
 rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
 clone(child_stack=0x7fa450df0ff0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD) = 464441
 munmap(0x7fa450de8000, 36864)           = 0
 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
 close(4)                                = 0
 fcntl(3, F_SETFD, 0)                    = 0
 fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
 read(3, "wlan0: \320\277\320\276\320\264\320\272\320\273\321\216\321\207\320\265\320\275\320\276 to H"..., 4096) = 39
 getpid()                                = 382320


 #ота собсна
 write(1, "ok 382320\n", 10)             = -1 EIO (Ошибка ввода/вывода)


 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=464441, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
 close(3)                                = 0
 wait4(464441, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 464441
 nanosleep({tv_sec=1, tv_nsec=0}, ^Cstrace: Process 382320 detached
  <detached ...>
 dron@gnu:~$ 

Как наладить с этой артисткой добрые отношения ввода вывода?


Да знааааю я надо сразу вывод перенаправить хоть изнутря в файл хоть с наружи. Но всё же ::)

★★★★★

Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)

Ответ на: комментарий от etwrq

Я знаю

dron@gnu:~$ ls /proc/382320/
arch_status      environ    mountinfo      personality   statm
attr             exe        mounts         projid_map    status
autogroup        fd         mountstats     root          syscall
auxv             fdinfo     net            sched         task
cgroup           gid_map    ns             schedstat     timers
clear_refs       io         numa_maps      sessionid     timerslack_ns
cmdline          limits     oom_adj        setgroups     uid_map
comm             loginuid   oom_score      smaps         wchan
coredump_filter  map_files  oom_score_adj  smaps_rollup
cpuset           maps       pagemap        stack
cwd              mem        patch_state    stat
dron@gnu:~$ 

А толку если

strace -p 382320
...
 write(1, "ok 382320\n", 10)             = -1 EIO (Ошибка ввода/вывода)
...

Или я всё же не знаю? =) Пни чуть конкретнее пожалуйста ^.^

dron@gnu:~$ ls -l /proc/382320/fd/
итого 0
lrwx------ 1 dron dron 64 фев 20 18:28 0 -> '/dev/pts/2 (deleted)'
lrwx------ 1 dron dron 64 фев 20 18:28 1 -> '/dev/pts/2 (deleted)'
lrwx------ 1 dron dron 64 фев 20 18:28 2 -> '/dev/pts/2 (deleted)'
dron@gnu:~$ 
LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)

а тупой вопрос – если приаттачиться к процессу gdb, вызвать там call open(«/tmp/xxx.txt», O_CREAT | O_WRONLY)? ну, если open вернет 1 – то збс.

demidrol ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

о, кстати, можешь еще глянть на dup2. Типа так

  1. аттачишься к дочке
  2. открываешь файл open(«/tmp/xxx.txt», …) и запоминаешь номер файлового дескриптора
  3. вызываешь dup2(<то, что вернул open>, 1)

все, по идее после этого 1 указывает на /tmp/xxx.txt

demidrol ★★★★★
()
Ответ на: комментарий от demidrol

Приатачитлся gdb -p 382320

(gdb) call open("/tmp/xxx.txt", O_WRONLY)
No symbol "O_WRONLY" in current context.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/dron/nm-check 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Detaching after fork from child process 472812]
процесс потомок 472812 создан
закрываю родительский 472806 процесс
[Inferior 1 (process 472806) exited normally]
(gdb) ok 472812
ok 472812
ok 472812

Убил дочку, завёл дугую. Не то что я завёл другую понял хотя яж того к процессу же. А вот почему убил прошлую так и не понял. Ой не эт всё нафиг и потом. Мне интересно как к восстановить оборванный канал =) А то тут вторая история получается уже

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от demidrol

Ща попробую, хотя странно… Я думал есть какой прямой способ восcтановить io. Ну типа умер /dev/pts/2 я типа ptsgen 2 и оно хлоп да поднялось опять =)

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Есть reptyr и redirect. Сам я их не пробовал. open() тоже может сработать (может есть ограничение на принадлежность к сессии, не помню), только надо константы числом писать.

xaizek ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

не тупи, посмотри в заголовочных файлах значения O_WRONLY. Это ж дефайн в сишном хедере.

O_CREAT | O_WRONLY = 0x41

т.е. в gdb юзай call open(«/tmp/xxx.txt», 0x41)

demidrol ★★★★★
()
Последнее исправление: demidrol (всего исправлений: 1)
Ответ на: комментарий от demidrol

Дай ой :D Я ещё тупил пока gdb прицеплен в новых io ничего не было, я аж растерялся и всё перенаправил :D

(gdb) p open("/tmp/io.txt",1)
$1 = 3
(gdb) p (int)dup2(3,0)
$2 = 0
(gdb) p (int)dup2(3,1)
$3 = 1
(gdb) p (int)dup2(3,2)
$4 = 2
(gdb) p open("/tmp/io2.txt",0x41)
$5 = 4
(gdb) p (int)dup2(4,4)
$6 = 4
q
dron@gnu:~$ ls -l /proc/516739/fd #пока открыто
итого 0
lrwx------ 1 dron dron 64 фев 20 20:48 0 -> /dev/pts/0
lrwx------ 1 dron dron 64 фев 20 20:48 1 -> /dev/pts/0
lrwx------ 1 dron dron 64 фев 20 20:48 2 -> /dev/pts/0
dron@gnu:~$ ls -l /proc/516739/fd #убил терминал
итого 0
lrwx------ 1 dron dron 64 фев 20 20:48 0 -> '/dev/pts/0 (deleted)'
lrwx------ 1 dron dron 64 фев 20 20:48 1 -> '/dev/pts/0 (deleted)'
lrwx------ 1 dron dron 64 фев 20 20:48 2 -> '/dev/pts/0 (deleted)'
dron@gnu:~$ ls -l /proc/516739/fd #ван (gdb отсоединить забыл)
итого 0
l-wx------ 1 dron dron 64 фев 20 20:48 0 -> /tmp/io.txt
lrwx------ 1 dron dron 64 фев 20 20:48 1 -> '/dev/pts/0 (deleted)'
lrwx------ 1 dron dron 64 фев 20 20:48 2 -> '/dev/pts/0 (deleted)'
l-wx------ 1 dron dron 64 фев 20 20:49 3 -> /tmp/io.txt
dron@gnu:~$ ls -l /proc/516739/fd #ту (gdb отсоединить забыл)
итого 0
l-wx------ 1 dron dron 64 фев 20 20:48 0 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:48 1 -> /tmp/io.txt
lrwx------ 1 dron dron 64 фев 20 20:48 2 -> '/dev/pts/0 (deleted)'
l-wx------ 1 dron dron 64 фев 20 20:49 3 -> /tmp/io.txt
dron@gnu:~$ ls -l /proc/516739/fd #сфри (gdb отсоединить забыл)
итого 0
l-wx------ 1 dron dron 64 фев 20 20:48 0 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:48 1 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:48 2 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:49 3 -> /tmp/io.txt
dron@gnu:~$ ls -l /proc/516739/fd #чатыря опомнился :D
итого 0
l-wx------ 1 dron dron 64 фев 20 20:48 0 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:48 1 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:48 2 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:49 3 -> /tmp/io.txt
l-wx------ 1 dron dron 64 фев 20 20:52 4 

тем временем рядышком

dron@gnu:~$ cat /proc/516739/fd/0
dron@gnu:~$ cat /proc/516739/fd/0
dron@gnu:~$ cat /proc/516739/fd/1
dron@gnu:~$ cat /proc/516739/fd/1
dron@gnu:~$ cat /proc/516739/fd/3
dron@gnu:~$ cat /proc/516739/fd/4
dron@gnu:~$ cat /proc/516739/fd/4
dron@gnu:~$ cat /proc/516739/fd/0 #гыыыы
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739
ok 516739

Спасибо большое, я пока читал и как понял если был закрыт управляющий терминал, то его невозможно востановить штатными средствами в угоду безопасности. Единственный способ внедрятся через отладку и подменять. Ну вот как насоветовали. Оно конечно спасибо. Теперь буду знать. Но как-то думалось существуют штатные (не ну я как понял можно заинжектить перенаправление без отладочных средств, но это уже костыль причём неимоверный, уж лучше gdb тогда).

Ну вроде всё. Интерес свой я удовлетворил, спасибо =)

А в демоне было до этого просто как O_WRONLY тобишь 1 просто, но с «w» я того бумбум ага :D Ну ничё зато весело

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от xaizek

reptyr

К живому умеет, захватывает и всё ок держит. К отвалившемуся io уже не умеет. redirect не проверял, но суть думаю таже. Но если как выше допёрли восстановить канал то всё подхватывает, но надо -s задавать иначе мимо. Спасибо за утилку, пригодится, не знал

LINUX-ORG-RU ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.