bugGNU gettext - Bugs: bug #43404, gl_locale_name_default() thread...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #43404: gl_locale_name_default() thread issues on OS X

Submitter:  Peter Eisentraut <petere>
Submitted:  Sat 11 Oct 2014 12:53:40 PM UTC
   
 
Category:  End-user / runtime Severity:  3 - Normal
Item Group:  None Status:  Wont Fix
Privacy:  Public Assigned to:  haible
Open/Closed:  Closed

Mon 12 Nov 2018 07:50:25 AM UTC, comment #2: 

I can think of two ways gl_locale_name_default() could avoid making a
single-threaded process multithreaded and also avoid the user-visible semantic
changes of the workarounds you list:

1. If the process is single-threaded, pipe(), fork(), and have the child call
   CFLocaleCopyCurrent().  Pass the result back in the pipe.  Otherwise (the
   process is already multithreaded), just call CFLocaleCopyCurrent() in the
   process that entered gl_locale_name_default(), like today.

2. pipe(), fork(), and exec() a helper executable that calls
   CFLocaleCopyCurrent() and passes the result back in the pipe.

(1) is better, since having a helper executable in a well-known location will
be too hard.  Both have the problems of fork() in a process that may not be
expecting it, like unplanned SIGCHLD handler execution and duplication of
output buffered in stdio before the fork().  Perhaps one could plug all those
holes (block SIGCHLD, exit child with raise(SIGKILL)).

Noah Misch <noah>
Sun 16 Sep 2018 07:05:52 PM UTC, comment #1: 

Indeed, I see two threads being created when single-stepping over the first call to CFLocaleCopyCurrent().

The stack traces from the post you referenced (attached here as threads.txt, for reference) show that
1. your program invokes libintl,
2. libintl invokes CoreFoundation,
3. CoreFoundation invokes libdispatch, which is the "Grand Central Dispatch", see https://apple.github.io/swift-corelibs-libdispatch/

Is CoreFoundation justified in doing that? Well, from an excerpt of CFLocale.c (attached) you can see that the CoreFoundation comes with its own type system; the type system needs to get initialized; and the dispatcher is used to guarantee once-only initialization. So, they use the dispatcher in really low-level parts of macOS. That's what macOS is like, today.

Is libintl justified in invoking CoreFoundation? Well, CoreFoundation is the only API in the system where you can reliably retrieve the user's language preferences. Either you do internationalization seriously, then you must use CoreFoundation. Or you implement a stub (which is what they have in their libc), which looks at environment variables but ignores what the user has set. For GNU gettext, I made the choice to take it seriously.

Should your program invoke libintl? Only you know.

I'm closing this as "Won't fix", because of the reasons stated above.

So, I'm not seeing many ways to work around it:
- Your program could stop using setlocale() - if it's not meaning to obey the user's settings.
- Your program could delay the setlocale() call until after fork().
- Maybe you can formalize a notion of programs that take their notion of "current locale" from elsewhere than from the user's settings, or where "the user" is a different concept? How would a program declare that it is such a beast?

(file #45023, file #45024)

Bruno Haible <haible>
Group administrator
Sat 11 Oct 2014 12:53:40 PM UTC, original submission:  

Something in libintl calls setlocale(), which calls gl_locale_name_default(), which calls CFLocaleCopyCurrent() on OS X.  Our analysis shows that CFLocaleCopyCurrent() spins up an additional thread, which causes all kinds of chaos in signal handlers and forked processes.  Here is the full analysis: http://www.postgresql.org/message-id/20140915045114.GA1332666@tornado.leadboat.com

Clearly, this is a somewhat special application, compared to all the single-threaded, single-process programs out there, but if adding gettext support to a server causes it to crash in random ways, that doesn't seem nice.

The original change in gettext/libintl is d4fd77b3f57a386b63083a7246ae5808510ac072.

Later in the above thread, a patch is proposed to move the Core Foundation calls into a subprocess, which you might be interested in.

Peter Eisentraut <petere>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #45023:  threads.txt added by haible (3KiB - text/plain)
file #45024:  CFLocale.c added by haible (650B - text/x-csrc)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by noah (Posted a comment)
  • -email is unavailable- added by haible (Updated the item)
  • -email is unavailable- added by noah
  • -email is unavailable- added by petere (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-09-16 haible Attached File- Added threads.txt, #45023
        Attached File- Added CFLocale.c, #45024
        StatusNone Wont Fix
        Assigned toNone haible
        Open/ClosedOpen Closed
    2016-11-27 haible CategoryNone End-user / runtime
    2014-10-11 noah Carbon-Copy- Added noah

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code