Package: boost-thread
Version: 1.49.0

I am currently working on a C++ app that runs on my PC just fine and I want
to make it work on a BeagleBone Black on which I have already installed a
Debian Wheezy.

I'm cross compiling using ELDK v5.3 and qmake from my PC (Intel Celeron,
Debian Wheezy, boost v1.49.0-3.2) to the BeagleBone Black (ARM Cortex A8,
Debian Wheezy, boost v1.49.0-3.2).

Everything works like it should, but every now and then, my app freezes (is
stuck on a __pthread_mutex_lock) when a boost::thread is created or the app
is waiting for a boost::thread::join().

I attached a small source code that generates a program that freezes in a
similar fashion when executed on the BeagleBone Black. There is also the
backtrace printed when the app freezes (GDB) and the .pro file used when
executing the qmake command.

It looks like an upgrade of boost to version 1.54 fixes the issue. But it
seems that Debian chose Boost 1.49.0 as a stable library for Wheezy so I
make this bug report even if it was already corrected in a newer release.

I've already posted this issue on Stackoverflow and Boost bug report :

http://stackoverflow.com/questions/18107163/application-boostthread-stuck-on-mutex-lock-when-compiled-for-arm-running-on-b

https://svn.boost.org/trac/boost/ticket/9086
(gdb) bt
#0  __libc_do_syscall () at 
../ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S:44
#1  0xb6756f92 in __lll_lock_wait (futex=0x1881c, private=0) at 
../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:47
#2  0xb675357a in __pthread_mutex_lock (mutex=0x1881c) at 
pthread_mutex_lock.c:61
#3  0xb68029dc in pthread_mutex_lock (mutex=<optimized out>) at forward.c:182
#4  0xb6991710 in lock (this=0xb69a2c68) at 
./boost/smart_ptr/detail/spinlock_pt.hpp:41
#5  scoped_lock (pv=0x1f714, this=<synthetic pointer>) at 
./boost/smart_ptr/detail/spinlock_pool.hpp:65
#6  atomic_increment (pw=0x1f714) at 
./boost/smart_ptr/detail/sp_counted_base_spin.hpp:41
#7  add_ref_copy (this=0x1f710) at 
./boost/smart_ptr/detail/sp_counted_base_spin.hpp:90
#8  shared_count (r=..., this=<optimized out>) at 
./boost/smart_ptr/detail/shared_count.hpp:316
#9  shared_ptr (this=<optimized out>) at ./boost/smart_ptr/shared_ptr.hpp:164
#10 operator= (r=..., this=0x1f604) at ./boost/smart_ptr/shared_ptr.hpp:311
#11 boost::thread::start_thread (this=0x1f5e8) at 
libs/thread/src/pthread/thread.cpp:185
#12 0x0000cf7c in boost::thread::thread<boost::_bi::bind_t<void, 
boost::_mfi::mf0<void, sub_dummy_class>, 
boost::_bi::list1<boost::_bi::value<sub_dummy_class*> > > > (this=0x1f5e8, 
f=...)
    at 
/opt/eldk-5.3/armv7a-hf/sysroots/armv7ahf-vfp-neon-linux-gnueabi/usr/include/boost/thread/detail/thread.hpp:205
#13 0x0000aa44 in sub_dummy_class::start (this=0x1cfdc) at main.cpp:51
#14 0x0000abc4 in dummy_class::start (this=0x1cf90) at main.cpp:96
#15 0x0000ac44 in main (argc=1, argv=0xbefff834) at main.cpp:109
#include <stdio.h>
#include <boost/thread.hpp>

#define NB_THREADS              20
#define THREAD_LIFE_DURATION    5

int g_nb_thread = 0;

boost::thread * subRegisterThread(boost::thread * pthread)
{
    printf("Register thread #%d  %p created\n",
        g_nb_thread++, pthread);

    return pthread;
}

/////////////////// Sub dummy class

class sub_dummy_class
{
public:
    boost::thread *mThread;

    sub_dummy_class();
    ~sub_dummy_class();
    void loop();
    void start();
};



sub_dummy_class::sub_dummy_class()
{
    mThread = NULL;
}

sub_dummy_class::~sub_dummy_class()
{
    if(mThread)
    {
        mThread->join();
    }
}

void sub_dummy_class::start()
{
    mThread = subRegisterThread(new boost::thread(boost::bind(&sub_dummy_class::loop, this)));
}

void sub_dummy_class::loop()
{
    int life_duration = THREAD_LIFE_DURATION;
    while(life_duration > 0)
    {
        life_duration--;
        printf("Got %d seconds to live !\n", life_duration);
        usleep(1000000);
    }
    return;
}


////////////////////////// Dummy class

class dummy_class
{
public:

    sub_dummy_class dummies[NB_THREADS];

    dummy_class();
    ~dummy_class();
    void start();


};

dummy_class::dummy_class()
{

}

dummy_class::~dummy_class()
{

}

void dummy_class::start()
{
    for(int i = 0 ; i < NB_THREADS ; i++)
    {
        dummies[i].start();
    }
}


int main(int argc, char* argv[])
{
    printf("Starting program\n");

    printf("Creating dummy class\n");
    dummy_class *DC = new dummy_class();

    printf("Starting dummy class\n");
    DC->start();

    printf("Deleting dummy class\n");
    delete DC;

    return 0;
}

Attachment: boost_thread_arm_test.pro
Description: Binary data

Reply via email to