From: | Noah Misch <noah(at)leadboat(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Andres Freund <andres(at)anarazel(dot)de>, pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: "could not adopt C locale" failure at startup on Windows |
Date: | 2015-06-15 06:11:00 |
Message-ID: | 20150615061100.GC333382@tornado.leadboat.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Wed, Jun 10, 2015 at 10:09:38AM -0400, Tom Lane wrote:
> Noah Misch <noah(at)leadboat(dot)com> writes:
> > I can reproduce this with "initdb --locale=C",
> > postgresql-9.4.3-1-windows-binaries.zip (32-bit), Windows 7 x64, and the
> > Windows ANSI code page set to CP936. (Choose "Chinese (Simplified, PRC)" in
> > Control Panel -> Region and Language -> Administrative -> Language for
> > non-Unicode programs.) It is neither necessary nor sufficient to change
> > Control Panel -> Region and Language -> Formats -> Format. Binaries from
> > postgresql-9.4.3-1-windows-x64-binaries.zip do not exhibit the problem. Note
> > that CP936 is a PG_ENCODING_IS_CLIENT_ONLY() encoding.
>
> Hm. I could understand getting encoding difficulties in that environment,
> but it's hard to see why they'd manifest like this. Can you trace through
> pg_perm_setlocale and figure out why it's reporting failure?
A faster test is to set LC_CTYPE=C in the environment and run "postgres
--version". The root cause is a bug my commit 5f538ad introduced at the start
of the 9.4 cycle. pg_perm_setlocale() now calls pg_bind_textdomain_codeset(),
which calls setlocale(LC_CTYPE, NULL). POSIX permits that to clobber all
previous setlocale() return values, which it did here[1]. The ensuing
putenv("LC_CTYPE=<garbage bytes>") at the end of pg_perm_setlocale() fails
under Windows ANSI code page 936, because the garbage bytes often aren't a
valid CP936 string. I would expect the same symptom on other multibyte
Windows locales.
While Windows was the bellwether, harm potential is greater on non-Windows
systems. pg_perm_setlocale() sets the LC_CTYPE environment variable to help
PL/Perl avoid clobbering the process locale; see plperl_init_interp()
comments. However, that function has bespoke code for Windows, on which
setting the environment variable doesn't help. I don't know which other
platforms invalidate previous setlocale() return values on setlocale(LC_CTYPE,
NULL). Therefore, I propose committing the attached diagnostic patch and
reverting it after about one buildfarm cycle. It will make affected
configurations fail hard, and then I'll have a notion about the prevalence of
damage to expect in the field.
The actual fix is trivial, attached second. This is for back-patch to 9.4.
[1] It does so in 32-bit "release" (non-debug), NLS builds done under Visual
Studio 2012 and Visual Studio 2013. The official binaries used VS2013. The
symptoms are slightly different under VS2012. I did not test earlier
versions. Debug builds and 64-bit builds were unaffected.
Attachment | Content-Type | Size |
---|---|---|
diagnose-setlocale-clobber-v1.patch | text/plain | 1.4 KB |
pg_perm_setlocale-clobber-v1.patch | text/plain | 604 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Amit Kapila | 2015-06-15 07:02:52 | Re: On columnar storage |
Previous Message | Josh Berkus | 2015-06-15 03:55:45 | Re: Moving Pivotal's Greenplum work upstream |