#10228 closed Bugs (worksforme)
boost::filesystem::path::parent_path crashes with static link
Reported by: | Owned by: | Beman Dawes | |
---|---|---|---|
Milestone: | Boost 1.56.0 | Component: | filesystem |
Version: | Boost 1.55.0 | Severity: | Problem |
Keywords: | Cc: |
Description
with following code
#include <string> #include <boost/filesystem.hpp> #include <stdint.h> #include <locale> #include <limits.h> #include <unistd.h> #include <sys/types.h> using namespace std; using namespace boost::filesystem; namespace __exeinfo_private { static std::string getexepath() { char result[PATH_MAX]; ssize_t count = readlink("/proc/self/exe", result, PATH_MAX); return std::string(result, count > 0 ? count : 0); } static int64_t get_current_process_id() { // from int32_t to int64_t return getpid(); } } static void run() { string _path = __exeinfo_private::getexepath(); path p(_path); if(!p.empty() && p.has_filename() && !p.parent_path().empty()) cout << p.filename().string() << endl << p.parent_path().string() << endl; } const static class ABC { private: ABC() { run(); } public: static const ABC& instance() { static const ABC i; return i; } }& instance = ABC::instance(); int main() { run(); }
compile with g++ exeinfo.cpp -lboost_filesystem -lboost_system, everything is ok, the output is expected as <the second and fourth lines are the path where the binary exists> a.out /home/hzj-jie/tmp a.out /home/hzj-jie/tmp
compile with g++ exeinfo.cpp -lboost_filesystem -lboost_system -static, static link with boost, the line 41, which is the constructor of ABC class will crash. the call stack is,
#0 0x0000000000433455 in std::locale::locale(std::locale const&) () #1 0x000000000040223c in boost::filesystem::path::codecvt() () #2 0x0000000000403927 in boost::filesystem::path::parent_path() const () #3 0x00000000004015d9 in run () at exeinfo.cpp:32 #4 0x0000000000401a77 in ABC::ABC (this=0x74ee60 <ABC::instance()::i>) at exeinfo.cpp:41 #5 0x0000000000401aaf in ABC::instance () at exeinfo.cpp:47 #6 0x00000000004017a5 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at exeinfo.cpp:50 #7 0x00000000004017c1 in _GLOBAL__sub_I_main () at exeinfo.cpp:55 #8 0x000000000045f5d7 in __libc_csu_init () #9 0x000000000045f079 in __libc_start_main () #10 0x00000000004013a7 in _start ()
according to some basic investigation, the trouble is coming from libs/filesystem/src/path.cpp, while the path_locale has not been initialized before ABC::ABC() running. because of the difference of implementation, in windows, no matter static or dynamic link, will not cause crash. please kindly let me know if this is by design, or has been fixed in the coming release, or if there were some work around.
thank you in advanced.
the environment i am now using is, Linux hzj-jie-x61t 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) but i have tried this on an x86 machine, which has the same experience.
Attachments (1)
Change History (11)
comment:1 by , 8 years ago
Component: | None → filesystem |
---|---|
Owner: | set to |
comment:2 by , 8 years ago
Status: | new → assigned |
---|
comment:3 by , 8 years ago
to install boost, 1. wget ... 2. gzip ... 3. tar ... 4. ./bootstrap.sh 5. ./b2 ; ./b2 install to compile the program shared link, g++ exeinfo.cpp -lboost_filesystem -lboost_system static link, g++ exeinfo.cpp -lboost_filesystem -lboost_system -static
comment:4 by , 8 years ago
Resolution: | → worksforme |
---|---|
Status: | assigned → closed |
I still can't reproduce the problem here, even doing the Boost install and test program build on a virtual machine exactly as you did.
Is it possible your locale is somehow messed up? For example, is your LANG environmental variable set to a valid locale?
Have you tried on a freshly built virtual machine? If the test program works statically in that environment, perhaps you can figure out what is different about the environment where the program is failing.
I'm closing the issue as "worksforme" since after quite a bit of effort I still can't reproduce the problem.
--Beman
comment:5 by , 8 years ago
my LANG environment variable has been set to LANG="en_US.UTF-8", which is default by my ubuntu installation. i am now trying with other distributions, but would you mind to tell me your environment variables, so i can figure out if anything different. following is the environment variables may be related.
declare -x LANG="en_US.UTF-8" declare -x LANGUAGE="en_US" declare -x LC_ADDRESS="zh_CN.UTF-8" declare -x LC_IDENTIFICATION="zh_CN.UTF-8" declare -x LC_MEASUREMENT="zh_CN.UTF-8" declare -x LC_MONETARY="zh_CN.UTF-8" declare -x LC_NAME="zh_CN.UTF-8" declare -x LC_NUMERIC="zh_CN.UTF-8" declare -x LC_PAPER="zh_CN.UTF-8" declare -x LC_TELEPHONE="zh_CN.UTF-8" declare -x LC_TIME="zh_CN.UTF-8"
comment:6 by , 8 years ago
detail frame is
#0 0x0000000000431555 in std::locale::locale(std::locale const&) () #1 0x0000000000403ce4 in boost::filesystem::path::imbue (loc=...) at libs/filesystem/src/path.cpp:918 #2 0x0000000000403c57 in boost::filesystem::path::codecvt () at libs/filesystem/src/path.cpp:911 #3 0x0000000000404200 in boost::filesystem::path::path<char const*> (this=0x7fffffffe3e0, begin=0x767bd8 "/root/a.out", end=0x767bdd "/a.out") at ./boost/filesystem/path.hpp:167 #4 0x000000000040249f in boost::filesystem::path::parent_path (this=0x7fffffffe3d0) at libs/filesystem/src/path.cpp:352 #5 0x0000000000401509 in run () at exeinfo.cpp:32 #6 0x00000000004019a7 in ABC::ABC (this=0x74de60 <ABC::instance()::i>) at exeinfo.cpp:41 #7 0x00000000004019df in ABC::instance () at exeinfo.cpp:47 #8 0x00000000004016d5 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at exeinfo.cpp:50 #9 0x00000000004016f1 in _GLOBAL__sub_I_main () at exeinfo.cpp:55 #10 0x000000000045d5e7 in __libc_csu_init () #11 0x000000000045d089 in __libc_start_main () #12 0x00000000004012d7 in _start ()
according to std lib implementation, the copy constructor of locale will copy the _M_impl pointer and add reference to it.
00058 locale::locale(const locale& __other) throw() 00059 : _M_impl(__other._M_impl) 00060 { _M_impl->_M_add_reference(); }
so if the path_locale._M_impl is nullptr, i.e. the constructor of path_locale has not been called, the copy constructor will crash. when the user trying to use static variable in functions, the logic may call the path::imbue before the constructor of path_locale, and cause the trouble.
i have tried to provide a fix, the principle is to define path_locale as a static variable in a function just as what windows implementation does. which can resolve the bug. the diff is,
root@hzj-ubuntu-1c:~# diff downloads/boost_1_55_0/libs/filesystem/src/path.cpp path.cpp 868,872c868 < inline std::locale path_locale() // initialized by path::codecvt() below < { < static std::locale loc; < return loc; < } --- > std::locale path_locale; // initialized by path::codecvt() below 922,923c918,919 < std::locale temp(path_locale()); < path_locale() = loc; --- > std::locale temp(path_locale); > path_locale = loc; 925c921 < &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale()); --- > &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale);
would you please have a look, if the proposal works?
thank you.
comment:7 by , 8 years ago
I'm having trouble applying your patch.
Please send me the complete modified path.cpp file.
Thanks,
--Beman
by , 8 years ago
comment:10 by , 8 years ago
Milestone: | To Be Determined → Boost 1.56.0 |
---|
I have not been able to reproduce the problem. Your test program runs fine for me for both static and shared linking. I'm testing on Ubuntu 14.4 LTS with gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2. Using b2 (i.e. bjam) to do the build.
How are you doing the build? What does your command line look like?
Thanks,
--Beman