Bug 121141 - std::shared_timed_mutex::try_lock_until causes assertion failure with negative timepoint
Summary: std::shared_timed_mutex::try_lock_until causes assertion failure with negativ...
Status: RESOLVED DUPLICATE of bug 116586
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-07-17 06:27 UTC by Dhruv Chawla
Modified: 2025-07-17 10:02 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dhruv Chawla 2025-07-17 06:27:45 UTC
The following code tries to have a call to try_lock_until () always fail because a negative timepoint has always been passed (per thread.timedmutex.requirements#general-11):

====

#include <chrono>
#include <shared_mutex>
#include <thread>

using SC = std::chrono::steady_clock;
using DU = std::chrono::duration<float, std::ratio<1, 5>>;

const std::chrono::time_point<SC, DU> tp{DU{-0.1f}};
std::shared_timed_mutex mut;

void thing() {
    (void)mut.try_lock_until(tp); 
}

int main() {
    mut.lock();
    std::thread t(thing);
    t.join();
}

====

Compilation options: -std=c++14

However this leads to a runtime error:

/opt/compiler-explorer/gcc-trunk-20250716/include/c++/16.0.0/shared_mutex:565: bool std::shared_timed_mutex::try_lock_until(const std::chrono::time_point<std::chrono::_V2::steady_clock, _Duration>&) [with _Duration = std::chrono::duration<float, std::ratio<1, 5> >]: Assertion '__ret == 0' failed.
Program terminated with signal: SIGSEGV

Compiler explorer link: https://godbolt.org/z/j7nbTcoz5

This is because the code in the standard library does not check the return value from pthread_rwlock_clockwrlock when the timepoint is negative:

	int __ret = pthread_rwlock_clockwrlock(&_M_rwlock, CLOCK_MONOTONIC,
					       &__ts);
	// On self-deadlock, we just fail to acquire the lock.  Technically,
	// the program violated the precondition.
	if (__ret == ETIMEDOUT || __ret == EDEADLK)
	  return false;
	// Errors not handled: EINVAL
	__glibcxx_assert(__ret == 0);
	return true;
Comment 1 Dhruv Chawla 2025-07-17 06:30:02 UTC
CC: Jonathan Wakely and Mike Crowe (for r10-5106-gab40695a46c664)
Comment 2 Jonathan Wakely 2025-07-17 10:02:28 UTC
This is Bug 116586

*** This bug has been marked as a duplicate of bug 116586 ***