[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[mono][sgen] Fix card scanning in LOS non-array objects - #125116

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan
Mar 5, 2026
Merged

[mono][sgen] Fix card scanning in LOS non-array objects#125116
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-sgen-card-scan

Conversation

@BrzVlad

Copy link
Copy Markdown
Member

sgen_card_table_region_begin_scanning needs to determine whether any cards are marked in the object starting at start address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether start + card_size < end => 500 + 512 < 520. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.

This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.

Fixes#124941

`sgen_card_table_region_begin_scanning` needs to determine whether any cards are marked in the object starting at `start` address. The current card size in 512 bytes. Consider an object with start 500 and size 20, so this object lives within 2 cards. We will check the card associated with the address 500. Once this iteration is done, we will check whether `start + card_size < end` => `500 + 512 < 520`. This is false, so we will no longer scan the second card. The algorithm was expecting the start address to be aligned to the card start, which is what the fix does.
This bug is severe, but, in practice, this code path is not as frequent. This bug would only affect objects greater than 8k, that are not arrays.
@BrzVlad
BrzVlad requested a review from steveisok as a code ownerMarch 3, 2026 13:43
CopilotAI review requested due to automatic review settings March 3, 2026 13:43
@BrzVlad
BrzVlad requested a review from lateralusXMarch 3, 2026 13:43
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes SGen card-table scanning for large (LOS) non-array objects when the object start address is not aligned to a card boundary, ensuring all cards that overlap the object are checked for marks before deciding whether to scan the object.

Changes:

  • Align the start address down to the containing card boundary in sgen_card_table_region_begin_scanning (overlapping-cards configuration).
  • Ensures multi-card objects that begin mid-card do not skip subsequent cards during the per-card iteration.

@lateralusXlateralusX left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@BrzVlad
BrzVlad merged commit 79898c7 into dotnet:mainMar 5, 2026
84 checks passed
@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/9.0-staging

@BrzVlad

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/9.0-staging (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

jozkee pushed a commit that referenced this pull request Mar 11, 2026
… objects (#125212)
Backport of #125116 to release/9.0-staging
/cc @BrzVlad
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
akoeplinger pushed a commit that referenced this pull request Mar 24, 2026
#125213)
Backport of #125116 to release/10.0
## Customer Impact
- [x] Customer reported
- [ ] Found internally
In some cases, cards marked for non-array LOS objects (objects with size
greater than 8K) were being ignored. This means that the GC could fail
to observe that some object refs were stored inside these large objects.
This can result in GC crashes or other undefined behavior. This can
impact all mono workloads. This issue was confirmed to be hit by a
customer who also investigated it via a GC debug flag. There are other
undiagnosed GC crashes that might hopefully be fixed by this.
## Regression
- [ ] Yes
- [x] No
## Testing
Was able to create a console app reproducing this bug. Validated the
fix.
## Risk
Low. The fix just does an address alignment, in order to scan correctly
an additional card.
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mono] Interpreter: Missing write barrier in Delegate field assignment (+=) causes GC consistency error and crash in Delegate.Remove

3 participants

@BrzVlad@lateralusX