#5928 closed Bugs (fixed)
FileSystem runtime error: locale::facet::_S_create_c_locale name not valid
Reported by: | anonymous | Owned by: | Beman Dawes |
---|---|---|---|
Milestone: | To Be Determined | Component: | filesystem |
Version: | Boost 1.47.0 | Severity: | Showstopper |
Keywords: | Cc: |
Description
I know this has been claimed to be fixed in v1.47. I thought so. Unfortunately, this is true only in SOME systems I believe. My application was compiled with:
-pedantic -static -m64 -O3
The binary works in many machines but the one I got problem with. It even runs a portion of the program but then throws the exception as shown in the title.
The machine in trouble got:
Linux xxx.xxx.xxx 2.6.18-164.6.1.el5 #1 SMP Tue Nov 3 16:12:36 EST 2009 x86_64 x86_64 x86_64 GNU/Linux
the output of g++ --version: g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)
Please take a look at this because it stops my binary from proceeding. THANK YOU SO MUCH Beman!
Change History (11)
comment:1 by , 11 years ago
follow-up: 3 comment:2 by , 11 years ago
Update: Oh I just realized i used the wrong machine to do the interactive test ... and now it turns out that the programs fails in the interactive sessions as well, as long LC_ALL isn't set to 'C'.
System: Linux mphy-s01 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux
follow-up: 4 comment:3 by , 11 years ago
Replying to midnight-runner@…:
Update: Oh I just realized i used the wrong machine to do the interactive test ... and now it turns out that the programs fails in the interactive sessions as well, as long LC_ALL isn't set to 'C'.
System: Linux mphy-s01 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux
I'm going to need a little test program that demonstrates this problem. My tests here all work perfectly, running fine if the environment is valid, otherwise throwing an exception after main() has started. So it would be very helpful to see your code that is failing, and be able to test with it here.
Thanks,
--Beman
follow-up: 5 comment:4 by , 11 years ago
Replying to bemandawes:
Replying to midnight-runner@…:
Update: Oh I just realized i used the wrong machine to do the interactive test ... and now it turns out that the programs fails in the interactive sessions as well, as long LC_ALL isn't set to 'C'.
System: Linux mphy-s01 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux
I'm going to need a little test program that demonstrates this problem. My tests here all work perfectly, running fine if the environment is valid, otherwise throwing an exception after main() has started. So it would be very helpful to see your code that is failing, and be able to test with it here.
Thanks,
--Beman
Ok I have prepared a few test cases with two different systems (different compilers). First of all, the problem occurs only if the programs are linked statically and only if codesample 1 is used. Codesample 2 works fine.
System 1 (Ubuntu 11.10): Linux XXX 3.0.0-15-server #25-Ubuntu SMP Mon Jan 2 19:14:55 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
System 2 (Ubuntu 09.10): Linux XXX 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
Boost with version 1.48 was employed and both systems use the same boost includes and libs (via nfs shares).
Codesample 1 (won't work if compiled statically with system 1 and running on system 2 with "incorrec LC-ALL"):
#include <boost/filesystem.hpp> int main ( int argc, char *argv[] ) { boost::filesystem::path path; std::string filename("readme.txt"); path = filename; // this isn't working // path = "readme.txt"; // this isn't working std::cout << "OK" << std::endl; return 0; }
Codesample 2 (works all the time):
#include <boost/filesystem.hpp> int main ( int argc, char *argv[] ) { boost::filesystem::path path("readme.txt"); std::cout << "OK" << std::endl; return 0; }
Compiling codesample 1 with system 1:
g++ main.cpp -o test_SYS-1_dyn -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH
g++ main.cpp -o test_SYS-1_sta -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH -static
Compiling codesample 1 with system 2:
g++ main.cpp -o test_SYS-2_dyn -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH
g++ main.cpp -o test_SYS-2_sta -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH -static
Running the programs:
With system 1:
and export LC-ALL='C':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
and export LC-ALL='en_GB.UTF-8':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
With system 2:
and export LC-ALL='C':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
and export LC-ALL='en_GB.UTF-8':
test_SYS-1_dyn:OK
test_SYS-1_sta:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
Aborted
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
Thanks,
Christian
comment:5 by , 11 years ago
Replying to midnight-runner@…:
Replying to bemandawes:
Replying to midnight-runner@…:
Update: Oh I just realized i used the wrong machine to do the interactive test ... and now it turns out that the programs fails in the interactive sessions as well, as long LC_ALL isn't set to 'C'.
System: Linux mphy-s01 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux
I'm going to need a little test program that demonstrates this problem. My tests here all work perfectly, running fine if the environment is valid, otherwise throwing an exception after main() has started. So it would be very helpful to see your code that is failing, and be able to test with it here.
Thanks,
--Beman
Ok I have prepared a few test cases with two different systems (different compilers). First of all, the problem occurs only if the programs are linked statically and only if codesample 1 is used. Codesample 2 works fine.
System 1 (Ubuntu 11.10): Linux XXX 3.0.0-15-server #25-Ubuntu SMP Mon Jan 2 19:14:55 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
System 2 (Ubuntu 09.10): Linux XXX 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
Boost with version 1.48 was employed and both systems use the same boost includes and libs (via nfs shares).
Codesample 1 (won't work if compiled statically with system 1 and running on system 2 with "incorrec LC-ALL"):
#include <boost/filesystem.hpp> int main ( int argc, char *argv[] ) { boost::filesystem::path path; std::string filename("readme.txt"); path = filename; // this isn't working // path = "readme.txt"; // this isn't working std::cout << "OK" << std::endl; return 0; }Codesample 2 (works all the time):
#include <boost/filesystem.hpp> int main ( int argc, char *argv[] ) { boost::filesystem::path path("readme.txt"); std::cout << "OK" << std::endl; return 0; }Compiling codesample 1 with system 1:
g++ main.cpp -o test_SYS-1_dyn -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH
g++ main.cpp -o test_SYS-1_sta -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH -staticCompiling codesample 1 with system 2:
g++ main.cpp -o test_SYS-2_dyn -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH
g++ main.cpp -o test_SYS-2_sta -L$LIB_PATH -lboost_system -lboost_filesystem -I$INCLUDE_PATH -staticRunning the programs:
With system 1:
and export LC-ALL='C':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
and export LC-ALL='en_GB.UTF-8':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
With system 2:
and export LC-ALL='C':
test_SYS-1_dyn:OK
test_SYS-1_sta:OK
test_SYS-2_dyn:OK
test_SYS-2_sta:OK
and export LC-ALL='en_GB.UTF-8':
test_SYS-1_dyn:OK
test_SYS-1_sta: terminate called after throwing an instance of 'std::runtime_error'what(): locale::facet::_S_create_c_locale name not valid
Aborted test_SYS-2_dyn:OK
test_SYS-2_sta:OK
Thanks,
Christian
I experienced similar problem when I linked statically to boost and runtime libraries; but the reason was not a Boost.
AFAIK the line
path = filename; // this isn't working
internally calls to some STL's functions. One of them eventually calls to codecvt() constructor which in turn calls to the newlocale(...)
function from glibc and throws the locale::facet::_S_create_c_locale
exception if newlocale() fails (i.e. returns 0).
The system where I built the application is Slackware 13.37 (like System 1 in your case) with glibc-2.13. But the system where the application was intended to run is Slackware 12.0 (System 2) with glibc-2.7
Trying to strace the application on System 2 shows that (as a result of a call to newlocale()) statically linked glibc-2.13 opens /usr/lib/locale/ru_RU.koi8r/LC_CTYPE file (I guess it would be /usr/lib/locale/en_GB.utf8/LC_CTYPE in your testcase) it stumbles upon incompatible version of this file (from glibc-2.7).
Exact file which is opened by call to glibc's newlocale() depends on LC_ALL (or LANG if no LC_ALL set) environment variable; but if LC_ALL/LANG is set to standard intrinsic locale (e.g. LC_ALL=C or LC_ALL=POSIX) then glibc-2.13 constructs the locale without opening any file, so the newlocale() call is successful in this case. If one manages to link application to runtime libraries dynamically (regretfully this is not my case) then the call to newlocale() would be successful too.
Hope this helps. Good luck.
follow-up: 7 comment:6 by , 10 years ago
I can reproduce this as well, the only difference beteween my "works" machine and "doesnt works" machine is the version of libstdc++ involved.
strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
Machine that doesn't work: list stops with GLIBCXX_3.4.13 Machine that does work: list stops with GLIBCXX_3.4.16
Test program to demonstrate crash:
#include <boost/filesystem.hpp> main() { boost::filesystem::path fp = boost::filesystem::current_path(); }
comment:7 by , 10 years ago
Replying to hugh.m.bright@…:
I can reproduce this as well, the only difference beteween my "works" machine and "doesnt works" machine is the version of libstdc++ involved.
strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
Machine that doesn't work: list stops with GLIBCXX_3.4.13 Machine that does work: list stops with GLIBCXX_3.4.16
Test program to demonstrate crash:
#include <boost/filesystem.hpp> main() { boost::filesystem::path fp = boost::filesystem::current_path(); }
But what does it tell about glibc version in your case? Please, try also
strings /usr/lib/libstdc++.so.6 | grep GLIBC
for this...
Thanks.
comment:8 by , 10 years ago
I can confirm the bug. Is there a patch available?
My GLIBC version goes up to 3.4.16. Other details of my system are:
libboost_filesystem.so.1.49.0
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
Ubuntu 11.10
Linux 3.1.0-1-amd64
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX | grep 3.4.16
GLIBCXX_3.4.16
comment:9 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Boost.Filesystem's implementation of path locale and codecvt handling has been rewritten with much simpler, more portable, and hopefully more robust code. The interface has not changed. The rewrite has been applied to svn trunk as of revision 83062. An added reference documentation section (boost-root/libs/filesystem/doc/reference.html#path-Usage) describes class path usage concerns, such as thread data races.
These changes should resolve this issue. If you believe it has not been resolved satisfactorily, please open a new issue rather than reopening this issue. But before you do that, please reread boost-root/libs/filesystem/doc/reference.html#path-Usage to be sure that the problem you are seeing is not a manifestation of one of the those concerns. If you do open a new issue, please be specific and supply a test case and lots of details. Just saying something "doesn't work" or "crashes" is not enough!
Thanks,
--Beman
comment:10 by , 8 years ago
Which release is revision 83062?
I see this behaviour on Solaris on 1.49. A call to unique_path() when LC_ALL is not set to C causes a crash as described above. Will attempt to verify on a later version.
comment:11 by , 8 years ago
For what it's worth, I was hitting this with version 1.51.0 when passing a char[] to any API that implicitly constructs a path. There is a template constructor that seems to jump into the locale-resolution stuff (codecvt, etc...).
Casting to or creating a const char * or a std::string seems to bypass that works as expected.
For example:
char dir[] = "/some/path"; boost::filesystem::exists( dir ); // runtime exception, perhaps dependent on env. locale boost::filesystem::exists( std::string( dir ) ); // works
There's a comment in path.hpp about this, so I'm not sure it should be called a bug or not...
Hope this helps.
I can confirm this, even though the problem is kind of strange ...
I'm using boost 1.47 and gcc 4.6.1 and doing static compilation as well. To run the program, I send the comandline (with parameters) to a cluster running the (sun) grid engine. Hence, I'm not in an interactive shell. If LC_ALL isn't set to 'C' in this shell (export LC_ALL=C) I will end up with "Error: locale::facet::_S_create_c_locale name not valid." However, if I log in to the maschine and execute the program without(!) setting LC_ALL to 'C', I can execute the program without problems.
Here's the system: Linux PC_NAME 2.6.38-10-server #46~lucid1-Ubuntu SMP Wed Jul 6 20:19:32 UTC 2011 x86_64 GNU/Linux