popen导致coredump
1 208 /* POSIX.2: "popen() shall ensure that any streams from previous 2 209 popen() calls that remain open in the parent process are closed 3 210 in the new child process." */ 4 211 for (p = proc_file_chain; p; p = p->next) 5 0x00007f2f1d52d515 <+645>: mov 0x359474(%rip),%rbp # 0x7f2f1d886990 <proc_file_chain> 6 0x00007f2f1d52d51c <+652>: jmp 0x7f2f1d52d531 <_IO_new_proc_open+673> 7 0x00007f2f1d52d52a <+666>: mov 0xe8(%rbp),%rbp 8 0x00007f2f1d52d531 <+673>: test %rbp,%rbp 9 0x00007f2f1d52d534 <+676>: jne 0x7f2f1d52d51e <_IO_new_proc_open+654> 10 11 212 { 12 213 int fd = _IO_fileno ((_IO_FILE *) p); 13 => 0x00007f2f1d52d51e <+654>: mov 0x70(%rbp),%edi 14 15 214 16 215 /* If any stream from previous popen() calls has fileno 17 216 child_std_end, it has been already closed by the dup2 syscall 18 217 above. */ 19 ---Type <return> to continue, or q <return> to quit--- 20 218 if (fd != child_std_end) 21 0x00007f2f1d52d521 <+657>: cmp %ebx,%edi 22 0x00007f2f1d52d523 <+659>: je 0x7f2f1d52d52a <_IO_new_proc_open+666> 23 24 219 _IO_close (fd); 25 0x00007f2f1d52d525 <+661>: callq 0x7f2f1d5ad049 <__close_nocancel> 26 27 220 } 28 29 30 disass: 31 0x00007f2f1d52d3e7 <+343>: mov 0x3595a2(%rip),%rax # 0x7f2f1d886990 <proc_file_chain> 32 0x00007f2f1d52d3ee <+350>: mov %r12,0x35959b(%rip) # 0x7f2f1d886990 <proc_file_chain> 33 0x00007f2f1d52d3f5 <+357>: mov %rax,0xe8(%r12) 34 35 instruction 1 : $rax = proc_file_chain; 36 instruction 2 : proc_file_chain = fp; 37 instruction 3 : fp->next = $rax (or proc_file_chain->next = $rax) 38 39 40 41 0x00000000000703da <+330>: jne 0x7066d <_L_lock_562> 42 0x00000000000703e0 <+336>: mov %rdx,0x3595a1(%rip) # 0x3c9988 <proc_file_chain_lock+8> 43 0x00000000000703e7 <+343>: mov 0x3595a2(%rip),%rax # 0x3c9990 <proc_file_chain> 44 ---Type <return> to continue, or q <return> to quit--- 45 0x00000000000703ee <+350>: mov %r12,0x35959b(%rip) # 0x3c9990 <proc_file_chain> 46 0x00000000000703f5 <+357>: mov %rax,0xe8(%r12) 47 0x00000000000703fd <+365>: mov 0x359581(%rip),%eax # 0x3c9984 <proc_file_chain_lock+4> 48 0x0000000000070403 <+371>: test %eax,%eax 49 50 51 52 0x00000000000703e0 <+336>: mov %rdx,0x3595a1(%rip) # 0x3c9988 <proc_file_chain_lock+8> 53 0x00000000000703e7 <+343>: mov 0x3595a2(%rip),%rax # 0x3c9990 <proc_file_chain> 54 ---Type <return> to continue, or q <return> to quit--- 55 0x00000000000703ee <+350>: addl $0x1,0x35958f(%rip) # 0x3c9984 <proc_file_chain_lock+4> 56 0x00000000000703f5 <+357>: mov %rax,0xe8(%r12) 57 0x00000000000703fd <+365>: subl $0x1,0x359580(%rip) # 0x3c9984 <proc_file_chain_lock+4> 58 0x0000000000070404 <+372>: mov %r12,0x359585(%rip) # 0x3c9990 <proc_file_chain> 59 0x000000000007040b <+379>: jne 0x7043c <_IO_new_proc_open+428> 60 0x000000000007040d <+381>: movq $0x0,0x359570(%rip) # 0x3c9988 <proc_file_chain_lock+8> 61 62 63 64 vim libio/iopopen.c 65 66 67 movq %rdx, proc_file_chain_lock+8(%rip) 68 .L57: 69 movq proc_file_chain(%rip), %rax 70 movq %r12, proc_file_chain(%rip) 71 movq %rax, 232(%r12) 72 movl proc_file_chain_lock+4(%rip), %eax 73 testl %eax, %eax 74 jne .L58 75 76 0x00007ffff78613e7 <+343>: mov 0x3595a2(%rip),%rax # 0x7ffff7bba990 <proc_file_chain> 77 ---Type <return> to continue, or q <return> to quit--- 78 0x00007ffff78613ee <+350>: mov %r12,0x35959b(%rip) # 0x7ffff7bba990 <proc_file_chain> 79 0x00007ffff78613f5 <+357>: mov %rax,0xe8(%r12) 80 instruction 1 : $rax = proc_file_chain; 81 instruction 2 : proc_file_chain = fp; 82 instruction 3 : fp->next = $rax (or proc_file_chain->next = $rax) 83 84 85 2 breakpoint keep y 0x00007ffff7861347 in _IO_new_proc_open at iopopen.c:180 thread 2 86 stop only in thread 2 87 breakpoint already hit 1 time 88 3 breakpoint keep y 0x00007ffff78613f5 in _IO_new_proc_open at iopopen.c:260 thread 1 89 stop only in thread 1 90 breakpoint already hit 1 time 91 92 break *(int *)0x00007ffff7861347 thread 2 93 c 94 set scheduler-locking on 95 thread 1 96 break *(int *)0x00007ffff78613f5 thread 1 97 98 99 100 101 print *(_IO_proc_file *)$r12 102 print ((_IO_proc_file *)$r12)->next 103 104 105 强制设置一个非法内存 106 set ((_IO_proc_file *)$r12)->next = 0x00702000 107 set scheduler-locking off
https://www.cygwin.com/bugzilla/show_bug.cgi?id=22834
https://github.com/bminor/glibc/commit/14d0e87d9b8caaa2eca7ca81f1189596671fe4fb
多线程执行popen在特定场景下导致子进程coredump,原因是编译器生成指令顺序不对,需要编译器屏障