On 24/09/15 07:20, Stephane Chazelas wrote: > 2015-09-24 07:01:23 +0100, Stephane Chazelas: >> 2015-09-23 21:27:00 -0400, Chet Ramey: >>> On 9/19/15 5:31 PM, Stephane Chazelas wrote: >>> >>>> In case it was caused by some Debian patch, I recompiled the >>>> code of 4.3.42 from gnu.org and the one from the devel branch on >>>> the git repository (commit bash-20150911 snapshot) and still: >>>> >>>> $ ./bash -c 'sh -c "trap exit INT; sleep 10; :"; echo hi' >>>> ^Chi >>>> $ ./bash -c 'sh -c "trap exit INT; sleep 10; :"; echo hi' >>>> ^Chi >>>> $ ./bash -c 'sh -c "trap exit INT; sleep 10; :"; echo hi' >>>> ^C >>>> $ ./bash -c 'sh -c "trap exit INT; sleep 10; :"; echo hi' >>>> ^Chi >>>> >>>> Sometimes (and the frequency of occurrences is erratic, >>>> generally roughly 80% of "hi"s but at times, I don't see a "hi" >>>> in a while), the "hi" doesn't show up. Note that I press ^C well >>>> after sleep has started. >>> >>> It would be nice to see a system call trace for this so we can check >>> what's going on with the timing. >> >> I don't have them logged but I did several tests in gdb >> with "handle SIGINT nostop pass" and as I said before, >> Upon the test that sets child_caught_sigint, waitpid() has not >> returned with EINTR and wait_sigint_received has been set. >> >> If I break on the SIGINT handler, I see the call trace at the >> return of the "syscall". >> >> I can try and get you a call trace later today. > [...] > > (gdb) handle SIGINT nostop pass > SIGINT is used by the debugger. > Are you sure you want to change it? (y or n) y > Signal Stop Print Pass to program Description > SIGINT No Yes Yes Interrupt > (gdb) break wait_sigint_handler > Breakpoint 1 at 0x443a70: file jobs.c, line 2241. > (gdb) run > Starting program: bash-4.3/bash -c ./a\;\ echo\ x > ^C > Program received signal SIGINT, Interrupt. > > Breakpoint 1, wait_sigint_handler (sig=2) at jobs.c:2241 > 2241 { > (gdb) bt > #0 wait_sigint_handler (sig=2) at jobs.c:2241 > #1 <signal handler called> > #2 0x00007ffff76bc31c in __libc_waitpid (pid=pid@entry=-1, > stat_loc=stat_loc@entry=0x7fffffffdbc8, options=options@entry=0) at > ../sysdeps/unix/sysv/linux/waitpid.c:31 > #3 0x0000000000445f3d in waitchld (block=block@entry=1, wpid=5337) at > jobs.c:3224 > #4 0x000000000044733b in wait_for (pid=5337) at jobs.c:2485 > #5 0x0000000000437992 in execute_command_internal > (command=command@entry=0x70bb88, asynchronous=asynchronous@entry=0, > pipe_in=pipe_in@entry=-1, pipe_out=pipe_out@entry=-1, > fds_to_close=fds_to_close@entry=0x70bde8) at execute_cmd.c:829 > #6 0x0000000000437b0e in execute_command (command=0x70bb88) at > execute_cmd.c:390 > #7 0x0000000000435f23 in execute_connection (fds_to_close=0x70bdc8, > pipe_out=-1, pipe_in=-1, asynchronous=0, command=0x70bd88) at > execute_cmd.c:2494 > #8 execute_command_internal (command=0x70bd88, > asynchronous=asynchronous@entry=0, pipe_in=pipe_in@entry=-1, > pipe_out=pipe_out@entry=-1, fds_to_close=fds_to_close@entry=0x70bdc8) > at execute_cmd.c:945 > #9 0x000000000047955b in parse_and_execute (string=<optimized out>, > from_file=from_file@entry=0x4b5f96 "-c", flags=flags@entry=4) at > evalstring.c:387 > #10 0x00000000004205d7 in run_one_command (command=<optimized out>) at > shell.c:1348 > #11 0x000000000041f524 in main (argc=3, argv=0x7fffffffe258, > env=0x7fffffffe278) at shell.c:695 > (gdb) frame 2 > #2 0x00007ffff76bc31c in __libc_waitpid (pid=pid@entry=-1, > stat_loc=stat_loc@entry=0x7fffffffdbc8, options=options@entry=0) at > ../sysdeps/unix/sysv/linux/waitpid.c:31 > 31 ../sysdeps/unix/sysv/linux/waitpid.c: No such file or directory. > (gdb) disassemble > Dump of assembler code for function __libc_waitpid: > 0x00007ffff76bc300 <+0>: mov 0x2f14cd(%rip),%r9d # > 0x7ffff79ad7d4 <__libc_multiple_threads> > 0x00007ffff76bc307 <+7>: test %r9d,%r9d > 0x00007ffff76bc30a <+10>: jne 0x7ffff76bc336 <__libc_waitpid+54> > 0x00007ffff76bc30c <+12>: xor %r10d,%r10d > 0x00007ffff76bc30f <+15>: movslq %edx,%rdx > 0x00007ffff76bc312 <+18>: movslq %edi,%rdi > 0x00007ffff76bc315 <+21>: mov $0x3d,%eax > 0x00007ffff76bc31a <+26>: syscall > => 0x00007ffff76bc31c <+28>: cmp $0xfffffffffffff000,%rax > 0x00007ffff76bc322 <+34>: ja 0x7ffff76bc325 <__libc_waitpid+37> > 0x00007ffff76bc324 <+36>: retq > 0x00007ffff76bc325 <+37>: mov 0x2ebb3c(%rip),%rdx # > 0x7ffff79a7e68 > 0x00007ffff76bc32c <+44>: neg %eax > 0x00007ffff76bc32e <+46>: mov %eax,%fs:(%rdx) > 0x00007ffff76bc331 <+49>: or $0xffffffffffffffff,%rax > (gdb) fin > Run till exit from #2 0x00007ffff76bc31c in __libc_waitpid > (pid=pid@entry=-1, stat_loc=stat_loc@entry=0x7fffffffdbc8, > options=options@entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:31 > 0x0000000000445f3d in waitchld (block=block@entry=1, wpid=5481) at jobs.c:3224 > 3224 pid = WAITPID (-1, &status, waitpid_flags); > Value returned is $5 = 5337 > (gdb) p wait_sigint_received > $6 = 1 > > In the other (working) cases, the difference is that waitpid() > returs -1 EINTR instead. > > Note that Bart on the zsh mailing list had noted something > similar already in 2009.
In case it's relevant, I'm not entirely sure of gdb's signal handling: https://sourceware.org/bugzilla/show_bug.cgi?id=18364