<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span style="font-size: 14px;" class="">Hello everyone,</span><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">I am new to this list. I am writing because I think I might have caught a bug in libc++. What I hope to get is a quick assessment of my issue so that I know if I should file this as a bug or some hints in how I should proceed to gather more information or even rectify the issue on my end.</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">The issue I am seeing popped up in a macOS project (Xcode 10.2.1) I am working on but I was able to condense it into a very small test program, see below for the code.</div><div style="font-size: 14px;" class=""><br class=""></div><div class=""><span style="font-size: 14px;" class="">The issue presents itself as a crash in shared_future::wait_for due to an uncatchable exception. The crash does not occur immediately but only after a (huge) number of calls. Console output in Xcode reads  "libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: condition_variable timed_wait failed: Invalid argument“. See backtrace further down for details. Unfortunately I cannot step into code of the method where the exception originates which is condition_variable::__do_timed_wait. I browsed the code in the libcxx repository and found that the error must be the result code EINVAL from a call to pthread_cond_timedwait.</span></div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">The interesting bit is that the issue can be reproduced in each test run within (mostly) less than 10 minutes on an iMac18,3/i7 and on a MacBookPro15,1/i7 but never on a MacBookPro15,2/i5. I only have one machine of each of those available so I cannot be sure how these results hold up.</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">1. Is there something fundamentally wrong with my code, i.e. how I use the shared_future?</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">2. Is this likely to be a bug in libc++ or is it more likely to be an issue with the BSD level API and/or the hardware? In case of the latter option where should I seek contact?</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">3. I would like to be able to step into the code for condition_variable::__do_timed_wait and get the debugger info for the local variables. Would this be simply a matter of pulling the libcxx repository, building and linking it? I am not a command line compilation guy so I was hoping for some good documentation on how to do this with and for Xcode. However, if must be, I am willing to accept my fate.</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">Thanks,</div><div style="font-size: 14px;" class="">Benjamin</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">Notes on the code below:</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">- The production code does not call sharedFuture.wait_for with 100ns. The production code currently uses 1ms which makes the issue pop up much less often, I saw half a day and three days, for example. 100ns has proven to trigger the exception much more often, that’s all.</div><div style="font-size: 14px;" class="">- FWIW, the same exception is thrown with shared_future::wait_until(steadyClockTimePoint), so steady clock accuracy does not seem to help.</div><div style="font-size: 14px;" class=""><br class=""></div><div style="font-size: 14px;" class="">__________________</div><div style="font-size: 14px;" class=""><br class=""></div><div class=""><span style="font-size: 14px;" class="">#include <future><br class="">#include <thread><br class=""><br class="">using namespace std;<br class=""><br class="">int main(int argc, const char * argv[])<br class="">{<br class="">   promise<void> thePromise = promise<void> {};<br class="">   shared_future<void> sharedFuture = thePromise.get_future().share();<br class="">   <br class="">   thread anotherThread = thread( [sharedFuture]<br class="">   {<br class="">      int debugCount = 0;<br class="">      while (sharedFuture.wait_for(100ns) == future_status::timeout)<br class="">      {<br class="">         debugCount++;<br class="">      }<br class="">   });</span></div><div class=""><span style="font-size: 14px;" class="">                                 <br class="">   sharedFuture.wait();<br class="">   <br class="">   return 0;<br class="">}</span></div><div class=""><span style="font-size: 14px;" class=""><br class=""></span></div><div class=""><span style="font-size: 14px;" class="">_________________</span></div><div class=""><span style="font-size: 14px;" class=""><br class=""></span></div><div class=""><span style="font-size: 14px;" class="">thread #1, queue = 'com.apple.main-thread'<br class="">    frame #0: 0x00007fff7f7fb86a libsystem_kernel.dylib`__psynch_cvwait + 10<br class="">    frame #1: 0x00000001003d11b2 libsystem_pthread.dylib`_pthread_cond_wait + 722<br class="">    frame #2: 0x00007fff7c6d2a0a libc++.1.dylib`std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 18<br class="">    frame #3: 0x00007fff7c6db96b libc++.1.dylib`std::__1::__assoc_sub_state::__sub_wait(std::__1::unique_lock<std::__1::mutex>&) + 45<br class="">    frame #4: 0x00007fff7c6db9d4 libc++.1.dylib`std::__1::__assoc_sub_state::wait() + 46<br class="">    frame #5: 0x0000000100000aa8 shared_future_wait_for`std::__1::shared_future<void>::wait(this=0x00007ffeefbff460) const at future:2561:34<br class="">    frame #6: 0x0000000100000932 shared_future_wait_for`main(argc=1, argv=0x00007ffeefbff4a0) at main.cpp:34:17<br class="">    frame #7: 0x00007fff7f6c33d5 libdyld.dylib`start + 1<br class="">* thread #2, stop reason = signal SIGABRT<br class="">    frame #0: 0x00007fff7f7fe2c6 libsystem_kernel.dylib`__pthread_kill + 10<br class="">    frame #1: 0x00000001003d080d libsystem_pthread.dylib`pthread_kill + 284<br class="">    frame #2: 0x00007fff7f7686a6 libsystem_c.dylib`abort + 127<br class="">    frame #3: 0x00007fff7c721641 libc++abi.dylib`abort_message + 231<br class="">    frame #4: 0x00007fff7c7217c7 libc++abi.dylib`default_terminate_handler() + 243<br class="">    frame #5: 0x00007fff7de97eeb libobjc.A.dylib`_objc_terminate() + 105<br class="">    frame #6: 0x00007fff7c72d19e libc++abi.dylib`std::__terminate(void (*)()) + 8<br class="">    frame #7: 0x00007fff7c72d213 libc++abi.dylib`std::terminate() + 51<br class="">    frame #8: 0x00007fff7c6daeeb libc++.1.dylib`__clang_call_terminate + 11<br class="">    frame #9: 0x00007fff7c6d2b73 libc++.1.dylib`std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock<std::__1::mutex>&, std::__1::chrono::time_point<std::__1::chrono::system_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >) + 159<br class="">  * frame #10: 0x00000001000020d3 shared_future_wait_for`std::__1::cv_status std::__1::condition_variable::wait_for<long long, std::__1::ratio<1l, 1000000000l> >(this=0x0000000100646e88, __lk=0x000070000a51bd48, __d=0x000070000a51bce0) at __mutex_base:416:9<br class="">    frame #11: 0x0000000100001e67 shared_future_wait_for`std::__1::cv_status std::__1::condition_variable::wait_until<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >(this=0x0000000100646e88, __lk=0x000070000a51bd48, __t=0x000070000a51bd98) at __mutex_base:384:5<br class="">    frame #12: 0x0000000100001cc2 shared_future_wait_for`std::__1::future_status std::__1::__assoc_sub_state::wait_until<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >(this=0x0000000100646e30, __abs_time=0x000070000a51bd98) const at future:604:15<br class="">    frame #13: 0x0000000100001bdf shared_future_wait_for`std::__1::future_status std::__1::__assoc_sub_state::wait_for<long long, std::__1::ratio<1l, 1000000000l> >(this=0x0000000100646e30, __rel_time=0x000070000a51be68) const at future:615:12<br class="">    frame #14: 0x0000000100001a60 shared_future_wait_for`std::__1::future_status std::__1::shared_future<void>::wait_for<long long, std::__1::ratio<1l, 1000000000l> >(this=0x00000001006431b8, __rel_time=0x000070000a51be68) const at future:2566:31<br class="">    frame #15: 0x00000001000018c0 shared_future_wait_for`main::$_0::operator(this=0x00000001006431b8)() const at main.cpp:18:30<br class="">    frame #16: 0x000000010000182d shared_future_wait_for`decltype(__f=0x00000001006431b8)()) std::__1::__invoke<main::$_0>(main::$_0&&) at type_traits:4339:1<br class="">    frame #17: 0x0000000100001795 shared_future_wait_for`void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0>(__t=size=2, (null)=__tuple_indices<> @ 0x000070000a51beb8) at thread:342:5<br class="">    frame #18: 0x0000000100000f66 shared_future_wait_for`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0> >(__vp=0x00000001006431b0) at thread:352:5<br class="">    frame #19: 0x00000001003cddc3 libsystem_pthread.dylib`_pthread_body + 126<br class="">    frame #20: 0x00000001003d0e8d libsystem_pthread.dylib`_pthread_start + 66<br class="">    frame #21: 0x00000001003cce11 libsystem_pthread.dylib`thread_start + 13<br class="">  thread #3<br class="">    frame #0: 0x00007fff7f7f9bfe libsystem_kernel.dylib`__workq_kernreturn + 10<br class="">    frame #1: 0x00000001003cd0ea libsystem_pthread.dylib`_pthread_wqthread + 634<br class="">    frame #2: 0x00000001003cce01 libsystem_pthread.dylib`start_wqthread + 13<br class=""><br class=""></span></div></body></html>