Red Hat Bugzilla – Bug 1470691
do not inline open_not_cancel; RFE: add open_not_cancel to API
Last modified: 2017-10-09 07:43:41 EDT
Description of problem: _nl_load_locale_from_archive() inlines a system call to open() as part of the implementation of open_not_cancel_2. Because open() is a natural sequence point in the logical flow, then inlining hinders user-level debugging of locale problems, and internal maintenance of the implementation itself, by making the open() hard to find (nm, readelf --symbols, etc.), trace (ltrace, etc.), and breakpoint (gdb, etc.) "strace -i" does reveal multiple sites for invocations of syscall open(), but finding and specifying those locations is cumbersome due to randomization of the placement of shared libraries upon each dl_open. So please put that syscall open() into a small, feature-specific, closed subroutine that has "open" as part of its name, and call the closed subroutine.
(Request For Enhancement [RFE]) Even better, the abstraction of open_not_cancel is useful outside of glibc, too. Please add an API so that user code can benefit, especially in a threaded environment. Thank you.
Version-Release number of selected component (if applicable):
How reproducible: every time
Steps to Reproduce:
1. "strace -i -e trace=open" of code that uses locale functionality
2. disassemble _nl_load_locale_from_archive in glibc shared library
3. Examine source code
[strace output omitted]
$ gdb /lib64/libc.so.6
(gdb) disassemble _nl_load_locale_from_archive
Dump of assembler code for function _nl_load_locale_from_archive:
=> 0x000000000002c9d3 <+1027>: mov $0x2,%ecx ## "#define __NR_open 2" /usr/include/asm/unistd_64.h
0x000000000002c9d8 <+1032>: mov $0x80000,%esi
0x000000000002c9dd <+1037>: lea 0x163c2c(%rip),%rdi # 0x190610 <archfname>
0x000000000002c9e4 <+1044>: mov %rax,0x394ffd(%rip) # 0x3c19e8 <archmapped>
0x000000000002c9eb <+1051>: mov %ecx,%eax
=> 0x000000000002c9ed <+1053>: syscall
0x000000000002c9ef <+1055>: cmp $0xfffffffffffff000,%rax
0x000000000002c9f5 <+1061>: mov %rax,%r15
0x000000000002c9f8 <+1064>: ja 0x2cabb <_nl_load_locale_from_archive+1259>
===== line 205
/* The archive has never been opened. */
fd = open_not_cancel_2 (archfname, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
===== line 401
fd = open_not_cancel_2 (archfname,
Expected results: Each invocation of syscall open() is discoverable within a small closed subroutine that has "open" as part of its name.
I don't think this is worth fixing. This is more of a GDB RFE for a way to break on specific system calls, or a better disassembler which knows about system calls.
open_not_cancel can be emulated easily with pthread_setcancelstate; this function is available even without linking against libpthread.