Skip to content
  • Takashi Iwai's avatar
    pager: don't use unsafe functions in signal handlers · 507d7804
    Takashi Iwai authored and Junio C Hamano's avatar Junio C Hamano committed
    Since the commit a3da8821 (pager: do wait_for_pager on signal
    death), we call wait_for_pager() in the pager's signal handler.  The
    recent bug report revealed that this causes a deadlock in glibc at
    aborting "git log" [*1*].  When this happens, git process is left
    unterminated, and it can't be killed by SIGTERM but only by SIGKILL.
    
    The problem is that wait_for_pager() function does more than waiting
    for pager process's termination, but it does cleanups and printing
    errors.  Unfortunately, the functions that may be used in a signal
    handler are very limited [*2*].  Particularly, malloc(), free() and the
    variants can't be used in a signal handler because they take a mutex
    internally in glibc.  This was the cause of the deadlock above.  Other
    than the direct calls of malloc/free, many functions calling
    malloc/free can't be used.  strerror() is such one, either.
    
    Also the usage of fflush() and printf() in a signal handler is bad,
    although it seems working so far.  In a safer side, we should avoid
    them, too.
    
    This patch tries to reduce the calls of such functions in signal
    handlers.  wait_for_signal() takes a flag and avoids the unsafe
    calls.   Also, finish_command_in_signal() is introduced for the
    same reason.  There the free() calls are removed, and only waits for
    the children without whining at errors.
    
    [*1*] https://bugzilla.opensuse.org/show_bug.cgi?id=942297
    [*2*] http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03
    
    
    
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    Reviewed-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    507d7804