Hi! On 2020-01-20T12:55:28+0100, I wrote: > While looking a bit into the item raised in > id:87muamgspy....@euler.schwinge.homeip.net I noticed the following > (mis?)behavior by notmuch. > > To set the stage: > > $ yes | head -n 1 > y > $ echo "${PIPESTATUS[@]}" > 141 0 > > As expected, the 'yes' process exits with SIGPIPE right after the 'head' > process terminated.
See also <https://pmhahn.github.io/SIGPIPE/>, for example. > However: > > $ notmuch search \* | head -n 1 & sleep 22; jobs; ps -f > [1] 622009 > thread:0000000000032bb2 the future [1/1] Jenna Moss; Steve Burbon, > Washington (hurd list spam) > [1]+ Running notmuch search \* | head -n 1 & > UID PID PPID C STIME TTY TIME CMD > thomas 621851 4297 0 12:38 pts/38 00:00:00 /bin/bash > thomas 622008 621851 99 12:48 pts/38 00:00:22 > /home/thomas/command/notmuch.real search \* > thomas 622013 621851 0 12:48 pts/38 00:00:00 ps -f > > Even after its "pipe-consumer" 'head' process has terminated, the > 'notmuch' process still keeps running, and running, and running... It > has to be killed manually (unless it before exits because of concurrent > database modification). This doesn't seem expected behavior to me? > > Now, I do have a patch or two (actually dozensa; reverts, WIP etc.) on > top of months-old notmuch sources, so I'll later try to reproduce that > with clean sources. $ gdb -q --args notmuch dump Reading symbols from notmuch... (gdb) break sigaction Breakpoint 1 at 0xe130 (gdb) r Starting program: [...]/notmuch dump [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, __GI___sigaction (sig=13, act=0x0, oact=0x7fffffffd4e0) at ../nptl/sigaction.c:24 24 ../nptl/sigaction.c: No such file or directory. (gdb) bt #0 0x00007ffff77e92f0 in __GI___sigaction (sig=13, act=0x0, oact=0x7fffffffd4e0) at ../nptl/sigaction.c:24 #1 0x00007ffff75bfa8d in () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #2 0x00007ffff75c64cd in gpgme_check_version () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #3 0x00007ffff75c6667 in gpgme_check_version_internal () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #4 0x00007ffff7f456b3 in g_mime_init () at /usr/lib/x86_64-linux-gnu/libgmime-3.0.so.0 #5 0x000055555556539d in main (argc=2, argv=0x7fffffffd828) at notmuch.c:469 So, libgpgme via libgmime initialization is doing something with signals. Here, 'sig=13' is SIGPIPE, 'act=0x0' means to just query, and store current handling into 'oact': (gdb) finish Run till exit from #0 __GI___sigaction (sig=13, act=0x0, oact=0x7fffffffd4e0) at ../nptl/sigaction.c:24 0x00007ffff75bfa8d in ?? () from /usr/lib/x86_64-linux-gnu/libgpgme.so.11 Value returned is $1 = 0 (gdb) print *(struct sigaction *) 0x7fffffffd4e0 $2 = {__sigaction_handler = {sa_handler = 0x0, sa_sigaction = 0x0}, sa_mask = {__val = {0, 8, 93824992565632, 0, 32, 88, 0, 22, 0, 140733193388034, 93823560581120, 7, 93824992559120, 32, 5, 93824992694848}}, sa_flags = 0, sa_restorer = 0x0} A '0x0' '__sigaction_handler' means 'SIG_DFL', which for SIGPIPE means to terminate the process. This is as expected. However, then: (gdb) continue Continuing. Breakpoint 1, __GI___sigaction (sig=13, act=0x7fffffffd4e0, oact=0x0) at ../nptl/sigaction.c:24 24 in ../nptl/sigaction.c (gdb) bt #0 0x00007ffff77e92f0 in __GI___sigaction (sig=13, act=0x7fffffffd4e0, oact=0x0) at ../nptl/sigaction.c:24 #1 0x00007ffff75bfadc in () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #2 0x00007ffff75c64cd in gpgme_check_version () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #3 0x00007ffff75c6667 in gpgme_check_version_internal () at /usr/lib/x86_64-linux-gnu/libgpgme.so.11 #4 0x00007ffff7f456b3 in g_mime_init () at /usr/lib/x86_64-linux-gnu/libgmime-3.0.so.0 #5 0x000055555556539d in main (argc=2, argv=0x7fffffffd828) at notmuch.c:469 (gdb) print *act $3 = {__sigaction_handler = {sa_handler = 0x1, sa_sigaction = 0x1}, sa_mask = {__val = {0 <repeats 16 times>}}, sa_flags = 0, sa_restorer = 0x0} A '0x1' '__sigaction_handler' means 'SIG_IGN', ignore any such signals. This is unexpected (to me, at least), not what I'd expect with notmuch? According to a (very quick) check/survey, this has apparently been the case "forever", and is documented on <https://www.gnupg.org/documentation/manuals/gpgme/Signal-Handling.html>, together with some rationale. Aha, aha, OK, I see. So, assuming we want to keep it that way (given the gpgme rationale), is the problem then that we fail to handle appropriately in notmuch any EPIPE that we may be getting from 'write' etc.? This remains to be explored another day. Grüße Thomas _______________________________________________ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch