Skip to content

Conversation

@ShreyaLaxminarayan
Copy link
Contributor

Problem:
During execution of the test TestAutoEnlistment_TxScopeComplete and TestAutoEnlistment_TxScopeNonComplete in Debug mode,a debug assertion fails on CoreCLR:
Method Debug.Fail failed with 'activated multiple times?

This occurs inside the DeactivateConnection method when returning a connection to the pool after a transaction completes.This assertion failure indicates that the internal _activateCount was already 0 when decrement was attempted again, deactivating the connection more than once.

Root Cause:
In the TransactionEnded function, after a transaction completes, the connection involved is returned to the general pool via:

Pool.PutObjectFromTransactedPool(transactedObject);

During this process, DeactivateConnection() is called again. However, the connection had already been deactivated earlier as part of the transaction's enlistment cleanup.This results in DeactivateConnection() being called twice without a corresponding call to ActivateConnection() in between, which causes _activateCount to decrement to -1, triggering the debug assertion.

Fix:
We prevent the second DeactivateConnection to decrement the _activateCount counter, by passing the parameter "false" to DeactivateConnection.

cc: @uweigand @giritrivedi @saitama951

Problem:
During execution of the test TestAutoEnlistment_TxScopeComplete and TestAutoEnlistment_TxScopeNonComplete in Debug mode,a debug assertion fails:
Method Debug.Fail failed with 'activated multiple times?

This occurs inside the DeactivateConnection method when returning a connection to the pool after a transaction completes.This assertion failure indicates that the internal _activateCount was already 0 when decrement was attempted again, deactivating the connection more than once.

Root Cause:
In "TransactionEnded" function,the connection used in a transaction is eventually returned to the general transaction pool via:
```Pool.PutObjectFromTransactedPool(transactedObject);```
The DeactivateConnection function is executed within this function which causes the _activateCount to be decremented a second time, resulting in a negative value and triggering the debug assertion. However,the connection had already been deactivated earlier as part of its transaction enlistment lifecycle
There is no subsequent ActivateConnection function for this DeactivateConnection function, which makes the _activateCount to to -1.

Fix:
We prevent the second DeactivateConnection to decrement the _activateCount counter, by passing the parameter "false" to DeactivateConnection.

cc: @uweigand @giritrivedi @saitama951
@ShreyaLaxminarayan ShreyaLaxminarayan requested a review from a team as a code owner August 29, 2025 06:52
@ShreyaLaxminarayan
Copy link
Contributor Author

@dotnet-policy-service agree company="IBM"

@paulmedynski
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Contributor

@paulmedynski paulmedynski left a comment

Choose a reason for hiding this comment

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

You can re-work things to eliminate the Debug.Assert() completely.

@paulmedynski
Copy link
Contributor

We've also been having some issues with macOS CI, which should be solved if you rebase or merge main.

@paulmedynski
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@paulmedynski
Copy link
Contributor

I'm also working on getting Debug mode PR pipelines to run successfully, and these Asserts() are causing trouble there as well. We will take your improvement, and I will decide whether or not these checks are valuable in my PR.

@apoorvdeshmukh
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@codecov
Copy link

codecov bot commented Sep 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.46%. Comparing base (cf2bdc7) to head (98fdd1c).
⚠️ Report is 29 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3587      +/-   ##
==========================================
- Coverage   63.19%   60.46%   -2.74%     
==========================================
  Files         274      268       -6     
  Lines       62478    61268    -1210     
==========================================
- Hits        39486    37048    -2438     
- Misses      22992    24220    +1228     
Flag Coverage Δ
addons ?
netcore 62.11% <ø> (-4.66%) ⬇️
netfx 64.61% <ø> (-1.57%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ShreyaLaxminarayan
Copy link
Contributor Author

Can we merge this?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a debug assertion failure in the connection pool where DeactivateConnection() was being called twice without a corresponding ActivateConnection() call, causing the _activateCount to decrement below zero.

Key Changes:

  • Modified the debug counter decrement logic to prevent double deactivation
  • Replaced simple Interlocked.Decrement with a compare-and-swap loop that checks for zero before decrementing

@paulmedynski paulmedynski merged commit 6b0c5c2 into dotnet:main Sep 17, 2025
236 checks passed
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.

4 participants