Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix clang thread safety analysis warnings #799

Conversation

MichaelOrlov
Copy link
Contributor

@MichaelOrlov MichaelOrlov commented Jun 30, 2021

Workaround for false positive findings by clang thread safety analysis in time controller jump callbacks API.
Address #795

Moved cv.notify_all() inside mutex lock scope, also made method process_callback() as non-static

…s in time controller jump callbacks API.

Moved cv.notify_all() inside mutex lock scope, also made method process_callback() as non-static

Signed-off-by: Michael Orlov <michael.orlov@apex.ai>
@MichaelOrlov
Copy link
Contributor Author

Gist:
https://gist.githubusercontent.com/MichaelOrlov/5fd70f1953b536179399721f25846a73/raw/fc9b346ecfc7d32e68197e58608448b6d2f3a1a9/ros2.repos

BUILD args: --packages-up-to rosbag2_cpp
TEST args: --packages-select rosbag2_cpp
Job: ci_launcher
ci_linux_clang_libcxx ran: https://ci.ros2.org/job/ci_linux_clang_libcxx/5/
Build Status

@MichaelOrlov MichaelOrlov marked this pull request as ready for review June 30, 2021 05:58
@MichaelOrlov MichaelOrlov requested a review from a team as a code owner June 30, 2021 05:58
@MichaelOrlov MichaelOrlov requested review from jaisontj, prajakta-gokhale, clalancette and emersonknapp and removed request for a team June 30, 2021 05:58
@MichaelOrlov MichaelOrlov self-assigned this Jun 30, 2021
Copy link
Collaborator

@emersonknapp emersonknapp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - however I will say that these are not false positives.

  • cv was used without the mutex
  • A static function does not have access to non-static member variables. The declaration of static void REQUIRES(member_) was ill-formed for requiring a non-static variable.

@MichaelOrlov
Copy link
Contributor Author

@emersonknapp As regards to the

  • cv was used without the mutex

cv.notify_all() should be used when mutex already unlocked. According to the https://en.cppreference.com/w/cpp/thread/condition_variable/notify_all

The notifying thread does not need to hold the lock on the same mutex as the one held by the waiting thread(s); in fact doing so is a pessimization, since the notified thread would immediately block again, waiting for the notifying thread to release the lock.

Implemented workaround putting cv.notify_all() under the mutex only works due to the specific optimization implemented in GCC. Tomorrow new type or version of compiler will be used or with some flags turning off this optimization and we will get random errors with missed notifications. I am actually not happy with such type of workarounds.

As regards to the:

A static function does not have access to non-static member variables. The declaration of static void REQUIRES(member_) was ill-formed for requiring a non-static variable.

Not sure if I understand you correctly but process_callback() function doesn't have access to the member variables of the class and purely operates with input parameters.

@MichaelOrlov
Copy link
Contributor Author

@emersonknapp Oh. BTW fun fact.
I didn't mind to declare process_callback() as static from the very beginning, but clang-tidy gave me a warning that this function could be declared as static and proposed to put static keyword for it. I reviewed this function and come to the conclusion so well why not.

Now we have contradiction between two tools clang-tidy and clang thread safety check :)

@emersonknapp
Copy link
Collaborator

emersonknapp commented Jun 30, 2021

cv.notify_all() should be used when mutex already unlocked

That is only according to the documented usage hints, it is not a requirement of the implementation. But, we explicitly said in the code that cv REQUIRES(mutex) - so the TSA is doing exactly what we told it to. It's not a false positive - it's an accurate result of the code that has been written.

Not sure if I understand you correctly but process_callback() function doesn't have access to the member variables of the class and purely operates with input parameters.

The static function was declared REQUIRES(non_static_member_) - there is no way for the static function to have access to that non-static-member. The compiler seems to allow this annotation without failing, but it's logically inconsistent so it would always raise a warning that the mutex is not held.

@MichaelOrlov MichaelOrlov merged commit 3bc6896 into master Jun 30, 2021
@delete-merged-branch delete-merged-branch bot deleted the michaelorlov/workaround-for-thread-safety-analysis-in-callbacks branch June 30, 2021 23:24
@emersonknapp emersonknapp changed the title Workaround for false positive findings by clang thread safety analysi… Fix clang thread safety analysis warnings Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants