> If this is the case, then use a memory barrier to ensure the write completes after setting the pointer to NULL. Johnathan is correct, the pthread_mutex_lock/unlock should be providing proper fencing around my critical section. However, I did as you suggested anyway just to ensure that wasn't the case. No dice, same problem. > Without looking at the code, I suggest trying GCC's -sanitize=thread option and/or valgrind's helgrind tool. I wasn't able to get -fsanitize=thread to compile. I moved to a VM with gcc 4.8+, installed libtsan0 (Trusty) and added the other flags (-pie etc) but it kept complaining the __tsan functions were undefined. Am I missing something to get this working? I was able to get helgrind to run. It pointed out 1 small issue but that isn't part of what I'm experiencing (I fixed it regardless). Helgrind affected the execution to an extent that instead of seeing (*buf)->id as 0 in thread 2, it sees it as 777 in thread 2, which is even more perplexing since thread 1 definitely set *buf to NULL within the critical section. I'm happy to provide any other code or info, or try other debugging tools. I'm getting desperate trying to track this down, so any help is appreciated. On Fri, Aug 21, 2015 at 11:30 AM, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > On 21 August 2015 at 19:25, Jeffrey Walton wrote: >> From the sounds of it, it sounds like its the same issue that used to >> occur with the double-checked locking initialization pattern. See, for >> example, http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/. > > Except that nothing is read outside the critical section guarded by the mutex. > >> If this is the case, then use a memory barrier to ensure the write >> completes after setting the pointer to NULL. > > pthread_mutex_unlock should be a release operation and > pthread_mutex_lock should be an acquire operation.