Project Home
Project Home
Source Code
Source Code
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - std::mutex::lock fails when on same stack address as another mutex before: (13 Items)
   
std::mutex::lock fails when on same stack address as another mutex before  
Hello,

I ported our C++11 application to QNX, but occasionally I get failures when trying to lock a std::mutex which resides on
 the stack. I'm currently testing this on SDP 6.6, but I also need to support SDP 6.5. This is why we are using libstdc+
+ instead of libcpp. 

I reduced the problem to the three minimal testcases (see attached). 
The problem seems to be that std::mutex initializes its pthread_mutex by PTHREAD_MUTEX_INITIALIZER. This mutex can be on
 the stack, but PTHREAD_MUTEX_INITIALIZER is only allowed for static (non-stack) variables 
See QNX_Neutrino_RTOS_C_Library_Reference.pdf (for SDP 6.6.0), p. 2317:
"You can initialize a _statically_ allocated mutex with the default attributes by assigning
to it the macro PTHREAD_MUTEX_INITIALIZER or
PTHREAD_RMUTEX_INITIALIZER (for recursive mutexes)."

Most modern OS have dropped the "statically" from the restrictons, thus libstdc++ uses PTHREAD_RMUTEX_INITIALIZER by 
default.

The workaround is to add -D_GTHREAD_USE_MUTEX_INIT_FUNC to the compile arguments. This should go 
into os_defines.h for a real fix (that's how libstdc++ does it on mingw)

Test cases: (run on the QNX 6.6.0 vmware image)

Stock SDP 6.6.0:
qcc tst_func.cpp -o tst_func -V4.7.3,gcc_ntox86_gpp -std=gnu++11 
qcc tst_loop.cpp -o tst_loop -V4.7.3,gcc_ntox86_gpp -std=gnu++11 
Both print  "std::mutex::lock caused std::system_error at i = 1 with code generic:22 meaning Invalid argument"

GCC 4.8.3 from linux-gcc-4.8.3-qnx660.tar.gz from this foundry27 project
qcc tst_func.cpp -o tst_func -V4.8.3,gcc_ntox86_gpp -std=gnu++11 
qcc tst_loop.cpp -o tst_loop -V4.8.3,gcc_ntox86_gpp -std=gnu++11 
Both print "std::mutex::lock caused std::system_error at i = 1 with code generic:22 meaning Invalid argument"

qcc tst_SyncMutexLock_r.cpp -o tst_SyncMutexLock_r
Both print "Second SyncMutexLock_r failed
Second SyncMutexUnlock_r failed"

Best wishes,
Matthias Gehre
Attachment: Text tst_loop.cpp 479 bytes Text tst_SyncMutexLock_r.cpp 566 bytes Text tst_func.cpp 501 bytes
Re: std::mutex::lock fails when on same stack address as another mutex before  
The same problem also affects rwlock and condition variables, which need -D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC -
D_GTHREAD_USE_COND_INIT_FUNC.
Re: std::mutex::lock fails when on same stack address as another mutex before  
The workaround is not working in all cases, because some code in libstdc++.so needs to be recompiled with those flags.

Test case:
i486-pc-nto-qnx6.6.0-g++ future_loop.cpp  -std=gnu++11 -o future_loop -static-libstdc++ -D_GTHREAD_USE_MUTEX_INIT_FUNC -
D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC -D_GTHREAD_USE_COND_INIT_FUNC -ggdb3 -O0
Crashes with
terminate called after throwing an instance of 'std::system_error'
  what():  Resource busy

With _GTHREAD_USE_MUTEX_INIT_FUNC, std::mutex destructor changes.
Because the destructor of std::future (more specifically: std::__future_base::_State_base::~_State_base) is compiled 
into libstdc++, it still calls the old destructor of std::mutex.

Can you please rebuild the gcc package with those changes, or give me instructions on how to do so?
Attachment: Text future_loop.cpp 253 bytes
Re: std::mutex::lock fails when on same stack address as another mutex before  
Hi Matthias,

Thank you for your report and analysis. I've open issue #1328672 to 
track the resolution. Attached is a libstdc++.so.6.0.17 built with the 
defines added to os_defines.h. After your test case no longer throws the 
exception.

Regards,

Ryan Mansfield
Attachment: Text libstdc++.so.6.0.17 4.92 MB
Re: std::mutex::lock fails when on same stack address as another mutex before  
Ryan,

Related: Check out case 00139008 and bug report (JIRA ID 812757)

- Cheers
RE: std::mutex::lock fails when on same stack address as another mutex before  
Is the file ok to use with GCC 4.8.3  on 650?  Or is it 660 only?
 
-----Message d'origine-----
De : Ryan Mansfield [mailto:community-noreply@qnx.com] 
Envoyé : 24 septembre 2015 13:57
À : general-toolchain@community.qnx.com
Objet : Re: std::mutex::lock fails when on same stack address as another mutex before

Hi Matthias,

Thank you for your report and analysis. I've open issue #1328672 to track the resolution. Attached is a libstdc++.so.6.0
.17 built with the defines added to os_defines.h. After your test case no longer throws the exception.

Regards,

Ryan Mansfield




_______________________________________________

General
http://community.qnx.com/sf/go/post114512
To cancel your subscription to this discussion, please e-mail general-toolchain-unsubscribe@community.qnx.com
Re: std::mutex::lock fails when on same stack address as another mutex before  
It was built for 660 and for libstdc++.so.6.0.17 (comes with gcc 4.7).

I'll have a look at the other issue to see if it's related.

Regards,

Ryan Mansfield
Re: std::mutex::lock fails when on same stack address as another mutex before  
Thank you for the fix.
Will this be included in a new "File release" of this project?
Re: std::mutex::lock fails when on same stack address as another mutex before  
> It was built for 660 and for libstdc++.so.6.0.17 (comes with gcc 4.7).
> 
> I'll have a look at the other issue to see if it's related.
> 
> Regards,
> 
> Ryan Mansfield

With Ryan gone, is there any hope of getting an updated 4.8.3 for QNX650 with this fix? Or is this a case of "told you 
not to use 6.5.0 and beta stuff".

Re: std::mutex::lock fails when on same stack address as another mutex before  
I'll take a look when I get some time.
Re: std::mutex::lock fails when on same stack address as another mutex before  
> I'll take a look when I get some time.

Doctor, any hope?
Re: std::mutex::lock fails when on same stack address as another mutex before  
Updated packages for 4.8 have been uploaded.
Re: std::mutex::lock fails when on same stack address as another mutex before  
Thank you!