fork() виснет при использовании ptrace
От: jek_  
Дата: 28.07.05 04:54
Оценка:
Проблема: процесс в одном из тредов делает fork(), входит в него (видно по backtrace-у в GDB), — его EIP указывает на инструкцию int 0x80, системный вызов произошел, перешли в режим ядра. В это время другой процесс (на самом деле тред той же программы, но в системе используется LinuxThreads, так что это на самом деле другой процесс) делает такую вещь (здесь pid — идентификатор процесса, только что вошедшего в fork()):

ptrace(PTRACE_ATTACH, pid, NULL, NULL);
waitpid(pid, status, __WALL);
ptrace(PTRACE_GETREGS, pid, NULL, &regs);
ptrace(PTRACE_DETACH, pid, NULL, NULL);

Все вызовы вовращают не-ошибочный код возврата, всё идёт хорошо.

Работало всё это очень долго — когда не было fork-ов. Но недавно оказалось, что в описанной ситуации первый процесс, входя в fork(), навсегда виснет. При этом дочерний процесс рожается и начинает свои действия, а parent навсегда зависает в форке!

Складывается такое впечатление, что resume его не происходит из-за того, что сигнал SIGCONT, посылаемый вызовом ptrace(PTRACE_DETACH, pid, NULL, NULL), просто не доходит до форкающегося процесса, по какой-то причине теряется. Если послать SIGCONT из консоли форкающимуся процессу, безнадёжно зависшему в fork(), он оживает и вся прилада едет дальше как ни в чём ни бывало!

Ума не приложу, почему SIGCONT может теряться? При этом тот waitpid исправно рапортует, что ошибки нет, что WIFSTOPPED(status)=true, и что WSTOPSIG(status)=SIGCONT...

В чём может быть дело?

Система у меня SuSE Linux 8.2, ядро 2.4.18.
Заранее спасибо за любую помощь!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.