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

Race in hb_ot_tags_from_language #3612

Closed
bungeman opened this issue May 26, 2022 · 13 comments
Closed

Race in hb_ot_tags_from_language #3612

bungeman opened this issue May 26, 2022 · 13 comments

Comments

@bungeman
Copy link
Collaborator

While rolling HarfBuzz in Chromium at https://chromium-review.googlesource.com/c/chromium/src/+/3668368 ThreadSanitizer detected a race which appears to be around hb_ot_tags_from_language. Still investigating.

@bungeman
Copy link
Collaborator Author

The race appears to be on last_tag_idx introduced in dfca47f [ot-tag] Cache last bsearch result

@bungeman
Copy link
Collaborator Author

bungeman commented May 26, 2022

I see that the intent here is to read from last_tag_idx exactly once to get a guess (and that guess may be anything, even uninitialized is fine) and write to it exactly once to store the next guess. However, in the absence of any barriers or volatile, there is nothing currently preventing the compiler from optimizing away last_tag_idx completely, or worse read from it multiple times, since in the absence of any annotation the compiler may assume single threaded execution and optimize as it wishes.

@behdad
Copy link
Member

behdad commented May 26, 2022

Thanks. I'll make it an atomic and use get/set_relaxed on it, which should satisfy thread-sanitizer.

@behdad
Copy link
Member

behdad commented May 26, 2022

That said, that optimization was a bit misguided. I'll revert it.

@behdad
Copy link
Member

behdad commented May 26, 2022

Let me measure and do one or the other.

@behdad
Copy link
Member

behdad commented May 27, 2022

I see that the intent here is to read from last_tag_idx exactly once to get a guess (and that guess may be anything, even uninitialized is fine) and write to it exactly once to store the next guess. However, in the absence of any barriers or volatile, there is nothing currently preventing the compiler from optimizing away last_tag_idx completely, or worse read from it multiple times, since in the absence of any annotation the compiler may assume single threaded execution and optimize as it wishes.

It's a static variable. It doesn't make any assumption on multiple threaded execution for effectiveness.

behdad added a commit that referenced this issue May 27, 2022
@behdad
Copy link
Member

behdad commented May 27, 2022

@bungeman Can you see if the commit I just pished fixes the sanitizer issue? Thanks.

@behdad behdad mentioned this issue May 28, 2022
@behdad
Copy link
Member

behdad commented May 28, 2022

Weird, I cannot reproduce this locally with our multithreaded test no matter how I try.

@bungeman
Copy link
Collaborator Author

At https://chromium-review.googlesource.com/c/chromium/src/+/3668368/3 attempting to roll HarfBuzz in Chromium to the commit to use atomic ints (before the change was reverted) to see if this alleviates the issue. If this lands it will be interesting to attempt to roll to the revert and see if it re-introduces the issue.

@behdad
Copy link
Member

behdad commented May 30, 2022

The revert was on a PR just to test.

@behdad
Copy link
Member

behdad commented May 30, 2022

The revert was on a PR just to test.

Actually I didn't mean the revert to go to main. But I see it did. That was not intentional. I'll revert the revert. Ouch.

@behdad
Copy link
Member

behdad commented May 30, 2022

I've confirmed locally using tsan that the atomic ops fix the issue.

@bungeman
Copy link
Collaborator Author

Thanks for updating the tests and reproducing. Can confirm that the roll of HarfBuzz into Chromium went well when rolling to the initial commit with the fix. After attempting a further roll ran into different issues. Will investigate and potentially open a different issue for that.

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

No branches or pull requests

2 participants