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 misleading/scary stack trace shown when an assertion occurs during node measurement #1022

Merged
merged 2 commits into from
Jul 12, 2018

Conversation

nguyenhuy
Copy link
Member

@nguyenhuy nguyenhuy commented Jul 12, 2018

  • Currently, there is a pair of mutex unlock and unlock that wraps around -_u_measureNodeWithBoundsIfNecessary: in __layout. That is because this method must be called without the lock.
  • When an assertion occurs within that method, the runtime bails early without reacquire the lock (so the lock is free now). However, the runtime then hits the end of the outmost mutex locker scope and tries to release the lock that it no longer holds, causing another assertion in ASThread to be shown to user (Assertion failure in void ASDN::Mutex::unlock()() #932) (see this video for more details). This makes it extremely hard to idenfity the root assertion.
  • Fix by replacing the unlock/lock pair with a mutex unlocker.

Closes #932

…rement

- Currently, there is a pair of mutex unlock and unlock that wraps around `-_u_measureNodeWithBoundsIfNecessary:` in `__layout`. That is because this method must be called without the lock.
- When an assertion occurs within that method, the runtime bails early without reacquire the lock (so the lock is free now). However, the runtime then hits the end of the outmost mutex locker scope and tries to release the lock that it no longer holds, causing another assertion in ASThread to be shown to user (TextureGroup#932). This makes it extremely hard to idenfity the root assertion.
- Fix by replacing the unlock/lock pair with a mutex unlocker.
Copy link
Member

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

Nice catch! Must've been a pain to diagnose.

@nguyenhuy nguyenhuy merged commit 5ffcd40 into TextureGroup:master Jul 12, 2018
nguyenhuy added a commit to nguyenhuy/Texture that referenced this pull request Jul 12, 2018
- Rename `ASDisplayNodeAssertLockUnownedByCurrentThread` to `ASDisplayNodeAssertLockNotHeld`, and `ASDisplayNodeAssertLockOwnedByCurrentThread` to `ASDisplayNodeAssertLockHeld` -> shorter and hopefully easier to distinguish between the two.
- Add assertions to `_locked_` and `_u_` (i.e "unlocked") methods.
- Turn `CHECK_LOCKING_SAFETY` flag on by default. After TextureGroup#1022 and TextureGroup#1023, we're in a good shape to actually enforce locked/unlocked requirements of internal methods. Our test suite passed, and we'll test more at Pinterest after the sync this week.
- Fix ASVideoNode to avoid calling `play` while holding the lock. That method inserts a subnode and must be called lock free.
- Other minor changes.
nguyenhuy added a commit that referenced this pull request Jul 13, 2018
- Rename `ASDisplayNodeAssertLockUnownedByCurrentThread` to `ASAssertUnlocked`, and `ASDisplayNodeAssertLockOwnedByCurrentThread` to `ASAssertLocked` -> shorter and hopefully easier to distinguish between the two.
- Add assertions to `_locked_` and `_u_` (i.e "unlocked") methods.
- Turn `CHECK_LOCKING_SAFETY` flag on by default. After #1022 and #1023, we're in a good shape to actually enforce locked/unlocked requirements of internal methods. Our test suite passed, and we'll test more at Pinterest after the sync this week.
- Fix ASVideoNode to avoid calling `play` while holding the lock. That method inserts a subnode and must be called lock free.
- Simplify `_loaded(node)` to only nil-check `_layer` because regardless of whether the node is view or layer backed, the layer should always be set if loaded. Use it throughout.
- Other minor changes.
mikezucc pushed a commit to mikezucc/Texture that referenced this pull request Oct 2, 2018
…g node measurement (TextureGroup#1022)

- Currently, there is a pair of mutex unlock and unlock that wraps around `-_u_measureNodeWithBoundsIfNecessary:` in `__layout`. That is because this method must be called without the lock.
- When an assertion occurs within that method, the runtime bails early without reacquire the lock (so the lock is free now). However, the runtime then hits the end of the outmost mutex locker scope and tries to release the lock that it no longer holds, causing another assertion in ASThread to be shown to user (TextureGroup#932). This makes it extremely hard to idenfity the root assertion.
- Fix by replacing the unlock/lock pair with a mutex unlocker.
mikezucc pushed a commit to mikezucc/Texture that referenced this pull request Oct 2, 2018
- Rename `ASDisplayNodeAssertLockUnownedByCurrentThread` to `ASAssertUnlocked`, and `ASDisplayNodeAssertLockOwnedByCurrentThread` to `ASAssertLocked` -> shorter and hopefully easier to distinguish between the two.
- Add assertions to `_locked_` and `_u_` (i.e "unlocked") methods.
- Turn `CHECK_LOCKING_SAFETY` flag on by default. After TextureGroup#1022 and TextureGroup#1023, we're in a good shape to actually enforce locked/unlocked requirements of internal methods. Our test suite passed, and we'll test more at Pinterest after the sync this week.
- Fix ASVideoNode to avoid calling `play` while holding the lock. That method inserts a subnode and must be called lock free.
- Simplify `_loaded(node)` to only nil-check `_layer` because regardless of whether the node is view or layer backed, the layer should always be set if loaded. Use it throughout.
- Other minor changes.
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

3 participants