Skip to content

Convert IDacDbiInterface to return HRESULT to fix cross-DSO exception handling on mobile platforms#124836

Merged
steveisok merged 6 commits intodotnet:mainfrom
steveisok:droid-debug-dac-hresult
Mar 2, 2026
Merged

Convert IDacDbiInterface to return HRESULT to fix cross-DSO exception handling on mobile platforms#124836
steveisok merged 6 commits intodotnet:mainfrom
steveisok:droid-debug-dac-hresult

Conversation

@steveisok
Copy link
Member

On mobile platforms, C++ exceptions thrown from DAC (libmscordaccore.so) are never caught by DBI (libmscordbi.so). This causes all ICorDebug operations that involve DAC calls to fail with E_FAIL.

Root cause:

Our mobile configurations statically link libc++ into each DSO. Combined with -fvisibility=hidden and -Bsymbolic, each DSO gets private copies of all C++ typeinfo. libc++'s RTTI uses pointer-only comparison (no string
fallback), so catch(Exception*) in DBI never matches exceptions thrown from DAC — the typeinfo pointers are different.

Solution

Convert all 119 non-HRESULT methods in IDacDbiInterface to return HRESULT, with former return values moved to OUT parameters. Each DAC implementation body is wrapped with EX_TRY/EX_CATCH_HRESULT so exceptions are caught inside the DAC and converted to HRESULT
before crossing the DSO boundary. DBI callers are updated to use IfFailThrow() to convert the HRESULT back to an exception within the DBI's own DSO, preserving existing error handling behavior.

This eliminates C++ exceptions crossing the DAC→DBI boundary entirely.

Changes

  • dacdbiinterface.h — 119 method signatures changed from void/value-returning to HRESULT + OUT parameter
  • dacdbiimpl.h — Matching implementation class declarations
  • dacdbiimpl.cpp, dacdbiimplstackwalk.cpp, dacdbiimpllocks.cpp — 119 method bodies wrapped with EX_TRY/EX_CATCH_HRESULT
  • 11 DBI caller files (process.cpp, rsthread.cpp, divalue.cpp, etc.) — 164 call sites updated to handle HRESULT returns

steveisok and others added 3 commits February 24, 2026 08:51
Change all 119 non-HRESULT virtual methods in IDacDbiInterface to
return HRESULT. Methods that previously returned values (BOOL, VMPTR_*,
ULONG, etc.) now take an additional OUT parameter. void methods simply
change their return type to HRESULT.

This is the interface declaration change for Approach E: eliminating
C++ exceptions crossing the DAC/DBI DSO boundary on Android.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Convert all 122 IDacDbiInterface method implementations to catch
exceptions and return HRESULT. Value-returning methods now write
results through OUT parameters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 25, 2026 00:52
@steveisok steveisok requested review from a team and jkotas February 25, 2026 00:53
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

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 updates the CoreCLR DBI↔DAC boundary to avoid C++ exceptions crossing DSOs on mobile platforms by converting IDacDbiInterface to an HRESULT-returning API (with previous return values moved to OUT parameters) and updating both DAC implementations and DBI call sites accordingly.

Changes:

  • Convert many IDacDbiInterface methods from void/value-returning to HRESULT + OUT parameter(s).
  • Update DBI (right-side) call sites to handle HRESULT (typically via IfFailThrow).
  • Update DAC implementations to catch/translate exceptions to HRESULT and return values via OUT parameters.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/coreclr/debug/inc/dacdbiinterface.h Converts interface methods to HRESULT + OUT params (API contract change).
src/coreclr/debug/daccess/dacdbiimpl.h Updates DAC-side class declarations to match new HRESULT signatures.
src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp Updates stackwalk-related DAC implementations to HRESULT and adds try/catch-to-HRESULT wrappers.
src/coreclr/debug/daccess/dacdbiimpllocks.cpp Updates lock-test DAC helpers to HRESULT with exception-to-HRESULT translation.
src/coreclr/debug/di/valuehome.cpp Updates handle-address fetch calls to use new OUT-parameter signature.
src/coreclr/debug/di/rstype.cpp Updates type-query DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsthread.cpp Updates thread-related DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsstackwalk.cpp Updates stackwalk DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsfunction.cpp Updates function/IL/native-info DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsclass.cpp Updates class/type/field-related DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsassembly.cpp Updates assembly path/trust DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/rsappdomain.cpp Updates AppDomain/object/module lookup DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/process.cpp Updates process-level DAC calls (init/heap/object/type/etc.) to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/module.cpp Updates module metadata/symbol/name-related DAC calls to HRESULT + OUT params with IfFailThrow.
src/coreclr/debug/di/divalue.cpp Updates value/object inspection DAC calls to HRESULT + OUT params with IfFailThrow (one call site still missing).

Copy link
Member

@noahfalk noahfalk left a comment

Choose a reason for hiding this comment

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

This change is a monster and if it subtlely didn't follow the pattern a few thousand lines in I doubt any human reviewer is going to notice. That said it seems like a fine pattern to go for and copilot seems to be finding the occasional mis-applications.

The cross-module exception handling I believe was also problematic even in desktop scenarios though perhaps not to the same degree. I consider this goodness across the board, not just for mobile.

Copilot AI review requested due to automatic review settings February 26, 2026 22:47
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.

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

@steveisok
Copy link
Member Author

@noahfalk can you give this another pass?

@steveisok steveisok enabled auto-merge (squash) March 2, 2026 11:59
@steveisok steveisok merged commit ad33dab into dotnet:main Mar 2, 2026
103 of 105 checks passed
@steveisok steveisok deleted the droid-debug-dac-hresult branch March 2, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants