diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 1ebbdf40d9acf2..5bc105a14f814c 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -1613,11 +1613,8 @@ ClrDataAccess::GetObjectStringData(CLRDATA_ADDRESS obj, unsigned int count, _Ino stringData[0] = W('\0'); } } - else - { - hr = E_INVALIDARG; - } + // A size-only query (no output buffer) reports the needed size via pNeeded and succeeds. if (pNeeded) *pNeeded = needed; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs index 2007bb81728a1e..08b0eb2b382acd 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs @@ -3456,17 +3456,25 @@ int ISOSDacInterface.GetObjectStringData(ClrDataAddress obj, uint count, char* s if (_legacyImpl is not null) { char[] stringDataLocal = new char[count]; - uint neededLocal; + uint neededLocal = 0; int hrLocal; fixed (char* ptr = stringDataLocal) { - hrLocal = _legacyImpl.GetObjectStringData(obj, count, ptr, &neededLocal); + // Invoke the legacy DAC under the same argument contract the caller gave the cDAC: + // only pass an output buffer when the caller did, and only request the size-out when + // the caller did. This keeps the HRESULT comparison apples-to-apples. + char* stringDataArg = stringData is null ? null : ptr; + uint* pNeededArg = pNeeded is null ? null : &neededLocal; + hrLocal = _legacyImpl.GetObjectStringData(obj, count, stringDataArg, pNeededArg); } + Debug.ValidateHResult(hr, hrLocal); if (hr == HResults.S_OK) { Debug.Assert(pNeeded == null || *pNeeded == neededLocal); - Debug.Assert(stringData == null || new ReadOnlySpan(stringDataLocal, 0, (int)neededLocal - 1).SequenceEqual(new string(stringData))); + // Compare against the legacy buffer using the cDAC string length: neededLocal is only + // populated when a size-out was requested from the legacy DAC (mirroring the caller). + Debug.Assert(stringData == null || new ReadOnlySpan(stringDataLocal, 0, new string(stringData).Length).SequenceEqual(new string(stringData))); } } #endif