【发布时间】:2021-02-09 14:58:12
【问题描述】:
在分析 iofclose.c 文件时,我发现了其中一些奇怪的部分。
// glibc-2.23.90/libio/iofclose.c:53
if (fp->_IO_file_flags & _IO_IS_FILEBUF)
_IO_un_link ((struct _IO_FILE_plus *) fp);
_IO_acquire_lock (fp); // !!!!! This part !!!!!
...
如您所见,fclose() 在内部调用 _IO_acquire_lock。
而_IO_acquire_lock 在此下方调用_IO_lock_lock。
//glibc-2.23.90/sysdeps/nptl/stdio-lock.h:39
#define _IO_lock_lock(_name) \
do { \
void *__self = THREAD_SELF; \
if ((_name).owner != __self) \
{ \
lll_lock ((_name).lock, LLL_PRIVATE); \
...
在_IO_lock_lock、void *__self = THREAD_SELF;和if ((_name).owner != __self)逻辑是这样出现的。
0x7f9a21eca393 <_IO_new_fclose+291>: mov r8,QWORD PTR fs:0x10
0x7f9a21eca39c <_IO_new_fclose+300>: cmp r8,QWORD PTR [rdx+0x8]
0x7f9a21eca3a0 <_IO_new_fclose+304>: je 0x7f9a21eca3e2 <_IO_new_fclose+370>
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
...
那么,如果在分支命令之后调用lll_lock((_name).lock, LLL_PRIVATE);,则lll_lock()会这样进行。
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
0x7f9a21eca3a7 <_IO_new_fclose+311>: xor eax,eax
0x7f9a21eca3a9 <_IO_new_fclose+313>:
cmp DWORD PTR [rip+0x35c390],0x0 # 0x7f9a22226740 <__libc_multiple_threads>
0x7f9a21eca3b0 <_IO_new_fclose+320>: je 0x7f9a21eca3ba <_IO_new_fclose+330>
...
在这个程序集中,比较__libc_multiple_threads的逻辑是。
但是,当我看到lll_lock() 代码时,我找不到那个逻辑......
//glibc-2.23.90/sysdeps/unix/sysv/linux/sparc/lowlevellock.h:51
static inline void
__attribute__ ((always_inline))
__lll_lock (int *futex, int private)
{
int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
if (__glibc_unlikely (val != 0))
{
if (__builtin_constant_p (private) && private == LLL_PRIVATE)
__lll_lock_wait_private (futex);
else
__lll_lock_wait (futex, private);
}
}
#define lll_lock(futex, private) __lll_lock (&(futex), private)
这种情况是怎么发生的?
在这个 c 源代码中哪里可以找到这些汇编逻辑?
【问题讨论】: