Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#10228 closed Bugs (worksforme)

boost::filesystem::path::parent_path crashes with static link

Reported by: hzj_jie@… 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)

path.cpp (27.9 KB ) - added by Hzj_jie <hzj_jie@…> 8 years ago.

Download all attachments as: .zip

Change History (11)

comment:1 by anonymous, 8 years ago

Component: Nonefilesystem
Owner: set to Beman Dawes

comment:2 by Beman Dawes, 8 years ago

Status: newassigned

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

comment:3 by anonymous, 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 Beman Dawes, 8 years ago

Resolution: worksforme
Status: assignedclosed

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 Hzj_jie <hzj_jie@…>, 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 Hzj_jie <hzj_jie@…>, 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 Beman Dawes, 8 years ago

I'm having trouble applying your patch.

Please send me the complete modified path.cpp file.

Thanks,

--Beman

by Hzj_jie <hzj_jie@…>, 8 years ago

Attachment: path.cpp added

comment:8 by Hzj_jie <hzj_jie@…>, 8 years ago

attached, thank you.

comment:9 by Hzj_jie <hzj_jie@…>, 8 years ago

i saw the issue has been fixed in 1.56, thank you for your time.

comment:10 by Beman Dawes, 8 years ago

Milestone: To Be DeterminedBoost 1.56.0
Note: See TracTickets for help on using tickets.