Bug 18015

Summary: X hangs in fork/SIGALRM loop at system("xkbcomp ...")
Product: Branch 4.0 Reporter: Konstantin Uvarin (lodin) <khedin>
Component: xorg-x11-serverAssignee: Valery Inozemtsev <shrek>
Status: CLOSED WONTFIX QA Contact: Q.A. 4.0 <qa-4.0>
Severity: normal    
Priority: P2    
Version: 4.0   
Hardware: all   
OS: Linux   

Description Konstantin Uvarin (lodin) 2008-11-27 10:49:41 MSK
В последнее время (без обновления чего-либо и т.п.) начали виснуть иксы при запуске некоторых приложений (замечено за OpenOffice-3 и dosemu). Курсор по экрану движется, но больше ничего не происходит и ctrl-alt-F1/BS/... тоже не работают.

Зайдя на машину удаленно и сделав 

strace -f -p `pgrep '^X$'`

, обнаруживаю следующее:

--- SIGALRM (Alarm clock) @ 0 (0) ---
sigreturn()                             = ? (mask now [])
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7c79a78) = ? ERESTARTNOINTR (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
sigreturn()                             = ? (mask now [])
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7c79a78) = ? ERESTARTNOINTR (To be restarted)

и так без конца. 

(Те же симптомы: https://qa.mandriva.com/show_bug.cgi?id=33639 )

Порывшись в исходниках иксов на предмет fork, обнаруживаю следующее:

========================================

os/utils.c, в функции Popen:

    /* Ignore the smart scheduler while this is going on */
    old_alarm = signal(SIGALRM, SIG_IGN);
    if (old_alarm == SIG_ERR) {
      perror("signal");
      return NULL;
    }
    
    switch (pid = fork()) {

====================================================

А вот выше, в функции system, такой предосторожности перед fork() нет. 

Заблаговременно запущенный strace -f -p также показывает, что в момент (успешного) запуска "проблемных" приложений происходит выполнение xkbcomp: 

execve("/bin/sh", ["sh"..., "-c"..., "\"/usr/bin/xkbcomp\" -w 1 \"-R/usr/"...], [/
* 26 vars */]) = 0

xkbcomp в исходниках Xorg, действительно, выполняется с помощью System. 

В исходниках последнего xorg из Сизифа (xorg-x11-server-1.4.0.90-alt21) то же различие: в Popen защита от аларма есть, а в System -- нет.

Возможно, ее стоит добавить. 

У меня самого иксы очень древние (из 4.0.0): xorg-x11-server-1.3.0.0-alt21.M40.1

Да, ещё. Баг не проявляется, если в консоли запущено что-то вроде 

strace -f -p `pgrep '^X$'` | grep -C5 ^clone

Видимо, создаваемой задержки хватает, чтобы цикла не возникало. А вот вывода strace в файл уже недостаточно.
Comment 1 Valery Inozemtsev 2008-11-27 11:15:42 MSK
в system оно тоже есть

#ifdef SIGCHLD
    csig = signal(SIGCHLD, SIG_DFL);
    if (csig == SIG_ERR) {
      perror("signal");
      return -1;
    }
#endif

#ifdef DEBUG
    ErrorF("System: `%s'\n", command);
#endif

    switch (pid = fork()) {
Comment 2 Valery Inozemtsev 2008-11-27 11:20:55 MSK
хотя в xorg-server-1.3 этой проверки действительно нет
Comment 3 Valery Inozemtsev 2009-02-01 23:13:20 MSK
для 4.0 исправлений уже не будет