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,原因是编译器生成指令顺序不对,需要编译器屏障

 

posted @ 2023-03-28 18:36  maojun1998  阅读(121)  评论(0编辑  收藏  举报