Bug 1470691 - do not inline open_not_cancel; RFE: add open_not_cancel to API
do not inline open_not_cancel; RFE: add open_not_cancel to API
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
x86_64 Linux
unspecified Severity unspecified
: ---
: ---
Assigned To: Carlos O'Donell
Fedora Extras Quality Assurance
Depends On:
  Show dependency treegraph
Reported: 2017-07-13 09:08 EDT by John Reiser
Modified: 2017-10-09 07:43 EDT (History)
8 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2017-10-09 07:43:41 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description John Reiser 2017-07-13 09:08:37 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

Actual results:
[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.

Additional info:
Comment 1 Florian Weimer 2017-10-09 07:43:41 EDT
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.

Note You need to log in before you can comment on or make changes to this bug.