From 991476eda8d68d4948b8c8ebd6ffb7e3c31d1229 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 22 Dec 2025 06:00:09 -0800 Subject: [PATCH 01/11] Synchronize GCInfoDecoder and GCInfoDumper with dotnet/runtime (#5672) The makes !gcinfo work correctly against current main --- src/shared/gcinfo/gcinfodumper.cpp | 16 ++- src/shared/inc/gcdecoder.cpp | 2 +- src/shared/inc/gcinfodecoder.h | 22 +-- src/shared/inc/gcinfotypes.h | 44 +++--- src/shared/vm/gcinfodecoder.cpp | 215 +++++++++++++---------------- 5 files changed, 141 insertions(+), 158 deletions(-) diff --git a/src/shared/gcinfo/gcinfodumper.cpp b/src/shared/gcinfo/gcinfodumper.cpp index cc7205ff14..ec53f6f440 100644 --- a/src/shared/gcinfo/gcinfodumper.cpp +++ b/src/shared/gcinfo/gcinfodumper.cpp @@ -194,7 +194,6 @@ BOOL GcInfoDumper::ReportPointerRecord ( #define vREG(reg, field) { offsetof(LoongArch64VolatileContextPointer, field) } vREG(zero, R0), REG(ra, Ra), - REG(tp, Tp), { offsetof(T_CONTEXT, Sp) }, vREG(a0, A0), vREG(a1, A1), @@ -360,7 +359,11 @@ PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this break; } #elif defined(TARGET_LOONGARCH64) - bool isVolatile = (iReg == 0 || (iReg >= 4 && iReg <= 21)); + if (iEncodedReg > 1) + { + iEncodedReg++; // We have to compensate for not tracking tp + } + bool isVolatile = (iReg == 0 || (iReg >= 3 && iReg <= 20)); if (ctx == 0) { if (!isVolatile) @@ -727,11 +730,9 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges ( *(ppCallerReg + iReg) = ®disp.pCallerContext->S0 + iReg; } - // Set Ra, Tp, Fp + // Set Ra, Fp regdisp.pCurrentContextPointers->Ra = ®disp.pCurrentContext->Ra; regdisp.pCallerContextPointers->Ra = ®disp.pCallerContext->Ra; - regdisp.pCurrentContextPointers->Tp = ®disp.pCurrentContext->Tp; - regdisp.pCallerContextPointers->Tp = ®disp.pCallerContext->Tp; regdisp.pCurrentContextPointers->Fp = ®disp.pCurrentContext->Fp; regdisp.pCallerContextPointers->Fp = ®disp.pCallerContext->Fp; @@ -862,7 +863,10 @@ PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on th #ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED UINT32 safePointOffset = offset; #if defined(TARGET_AMD64) || defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) - safePointOffset++; + if (safePointDecoder.Version() < 4) + { + safePointOffset++; + } #endif if(safePointDecoder.IsSafePoint(safePointOffset)) { diff --git a/src/shared/inc/gcdecoder.cpp b/src/shared/inc/gcdecoder.cpp index 26001f5889..541011b5f7 100644 --- a/src/shared/inc/gcdecoder.cpp +++ b/src/shared/inc/gcdecoder.cpp @@ -197,7 +197,7 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header header->syncStartOffset ^= HAS_SYNC_OFFSET; break; case FLIP_REV_PINVOKE_FRAME: - header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET ? HAS_REV_PINVOKE_FRAME_OFFSET : INVALID_REV_PINVOKE_OFFSET; + header->revPInvokeOffset ^= (INVALID_REV_PINVOKE_OFFSET ^ HAS_REV_PINVOKE_FRAME_OFFSET); break; case NEXT_OPCODE: diff --git a/src/shared/inc/gcinfodecoder.h b/src/shared/inc/gcinfodecoder.h index 450e1fbf2f..a207310361 100644 --- a/src/shared/inc/gcinfodecoder.h +++ b/src/shared/inc/gcinfodecoder.h @@ -218,7 +218,7 @@ enum GcInfoDecoderFlags DECODE_INTERRUPTIBILITY = 0x08, DECODE_GC_LIFETIMES = 0x10, DECODE_NO_VALIDATION = 0x20, - DECODE_PSP_SYM = 0x40, + DECODE_PSP_SYM = 0x40, // Unused starting with v4 format DECODE_GENERICS_INST_CONTEXT = 0x80, // stack location of instantiation context for generics // (this may be either the 'this' ptr or the instantiation secret param) DECODE_GS_COOKIE = 0x100, // stack location of the GS cookie @@ -237,7 +237,7 @@ enum GcInfoHeaderFlags GC_INFO_IS_VARARG = 0x1, // unused = 0x2, // was GC_INFO_HAS_SECURITY_OBJECT GC_INFO_HAS_GS_COOKIE = 0x4, - GC_INFO_HAS_PSP_SYM = 0x8, + GC_INFO_HAS_PSP_SYM = 0x8, // Unused starting with v4 format GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK = 0x30, GC_INFO_HAS_GENERICS_INST_CONTEXT_NONE = 0x00, GC_INFO_HAS_GENERICS_INST_CONTEXT_MT = 0x10, @@ -248,6 +248,8 @@ enum GcInfoHeaderFlags GC_INFO_WANTS_REPORT_ONLY_LEAF = 0x80, #elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) GC_INFO_HAS_TAILCALLS = 0x80, +#else + // unused = 0x80, #endif // TARGET_AMD64 GC_INFO_HAS_EDIT_AND_CONTINUE_INFO = 0x100, GC_INFO_REVERSE_PINVOKE_FRAME = 0x200, @@ -300,7 +302,7 @@ class BitStreamReader } // NOTE: This routine is perf-critical - __forceinline size_t Read( int numBits ) + FORCEINLINE size_t Read( int numBits ) { SUPPORTS_DAC; @@ -325,7 +327,7 @@ class BitStreamReader // This version reads one bit // NOTE: This routine is perf-critical - __forceinline size_t ReadOneFast() + FORCEINLINE size_t ReadOneFast() { SUPPORTS_DAC; @@ -346,13 +348,13 @@ class BitStreamReader } - __forceinline size_t GetCurrentPos() + FORCEINLINE size_t GetCurrentPos() { SUPPORTS_DAC; return (size_t) ((m_pCurrent - m_pBuffer) * BITS_PER_SIZE_T + m_RelPos - m_InitialRelPos); } - __forceinline void SetCurrentPos( size_t pos ) + FORCEINLINE void SetCurrentPos( size_t pos ) { size_t adjPos = pos + m_InitialRelPos; m_pCurrent = m_pBuffer + adjPos / BITS_PER_SIZE_T; @@ -364,7 +366,7 @@ class BitStreamReader _ASSERTE(GetCurrentPos() == pos); } - __forceinline void Skip( SSIZE_T numBitsToSkip ) + FORCEINLINE void Skip( SSIZE_T numBitsToSkip ) { SUPPORTS_DAC; @@ -416,7 +418,7 @@ class BitStreamReader } } - __forceinline size_t DecodeVarLengthUnsigned(int base) + FORCEINLINE size_t DecodeVarLengthUnsigned(int base) { _ASSERTE((base > 0) && (base < (int)BITS_PER_SIZE_T)); @@ -583,6 +585,7 @@ class TGcInfoDecoder INT32 GetReversePInvokeFrameStackSlot(); bool HasMethodDescGenericsInstContext(); bool HasMethodTableGenericsInstContext(); + bool HasStackBaseRegister(); bool GetIsVarArg(); bool WantsReportOnlyLeaf(); #if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) @@ -780,6 +783,9 @@ class TGcInfoDecoder }; typedef TGcInfoDecoder GcInfoDecoder; +#ifdef FEATURE_INTERPRETER +typedef TGcInfoDecoder InterpreterGcInfoDecoder; +#endif // FEATURE_INTERPRETER #endif // USE_GC_INFO_DECODER diff --git a/src/shared/inc/gcinfotypes.h b/src/shared/inc/gcinfotypes.h index 10d22d6709..5736efb3f1 100644 --- a/src/shared/inc/gcinfotypes.h +++ b/src/shared/inc/gcinfotypes.h @@ -211,15 +211,6 @@ inline bool IsPointerFieldReturnKind(ReturnKind returnKind) return (returnKind == RT_Object || returnKind == RT_ByRef); } -inline bool IsValidReturnRegister(size_t regNo) -{ - return (regNo == 0) -#ifdef FEATURE_MULTIREG_RETURN - || (regNo == 1) -#endif // FEATURE_MULTIREG_RETURN - ; -} - inline bool IsStructReturnKind(ReturnKind returnKind) { // Two bits encode integer/ref/float return-kinds. @@ -260,7 +251,6 @@ inline ReturnKind GetStructReturnKind(ReturnKind reg0, ReturnKind reg1) inline ReturnKind ExtractRegReturnKind(ReturnKind returnKind, size_t returnRegOrdinal, bool& moreRegs) { _ASSERTE(IsValidReturnKind(returnKind)); - _ASSERTE(IsValidReturnRegister(returnRegOrdinal)); // Return kind of each return register is encoded in two bits at returnRegOrdinal*2 position from LSB ReturnKind regReturnKind = (ReturnKind)((returnKind >> (returnRegOrdinal * 2)) & 3); @@ -818,18 +808,18 @@ struct RISCV64GcInfoEncoding { // GC Pointers are 8-bytes aligned static inline constexpr int32_t NORMALIZE_STACK_SLOT (int32_t x) { return ((x)>>3); } static inline constexpr int32_t DENORMALIZE_STACK_SLOT (int32_t x) { return ((x)<<3); } - // All Instructions are 4 bytes long - static inline constexpr uint32_t NORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)>>2); } - static inline constexpr uint32_t DENORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)<<2); } + // All Instructions are 2/4 bytes long + static inline constexpr uint32_t NORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)>>1); } + static inline constexpr uint32_t DENORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)<<1); } // Encode Frame pointer X8 as zero, sp/x2 as 1 static inline constexpr uint32_t NORMALIZE_STACK_BASE_REGISTER (uint32_t x) { return ((x) == 8 ? 0u : 1u); } static inline constexpr uint32_t DENORMALIZE_STACK_BASE_REGISTER (uint32_t x) { return ((x) == 0 ? 8u : 2u); } static inline constexpr uint32_t NORMALIZE_SIZE_OF_STACK_AREA (uint32_t x) { return ((x)>>3); } static inline constexpr uint32_t DENORMALIZE_SIZE_OF_STACK_AREA (uint32_t x) { return ((x)<<3); } static const bool CODE_OFFSETS_NEED_NORMALIZATION = true; - // Instructions are 4 bytes long - static inline constexpr uint32_t NORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)>>2); } - static inline constexpr uint32_t DENORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)<<2); } + // Instructions are 2/4 bytes long + static inline constexpr uint32_t NORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)>>1); } + static inline constexpr uint32_t DENORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)<<1); } static const int PSP_SYM_STACK_SLOT_ENCBASE = 6; static const int GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE = 6; @@ -864,13 +854,7 @@ struct RISCV64GcInfoEncoding { static const int LIVESTATE_RLE_SKIP_ENCBASE = 4; }; -#else // defined(TARGET_xxx) - -#ifndef TARGET_X86 -#ifdef PORTABILITY_WARNING -PORTABILITY_WARNING("Please specialize these definitions for your platform!") -#endif -#endif +#elif defined(TARGET_X86) #ifndef TARGET_POINTER_SIZE #define TARGET_POINTER_SIZE 4 // equal to sizeof(void*) and the managed pointer size in bytes for this target @@ -924,6 +908,20 @@ struct X86GcInfoEncoding { static const int LIVESTATE_RLE_SKIP_ENCBASE = 4; }; +#elif defined(TARGET_WASM) + +#ifndef TARGET_POINTER_SIZE +#define TARGET_POINTER_SIZE 4 // equal to sizeof(void*) and the managed pointer size in bytes for this target +#endif + +#define TargetGcInfoEncoding InterpreterGcInfoEncoding + +#else // No target defined + +#ifdef PORTABILITY_WARNING +PORTABILITY_WARNING("Please specialize these definitions for your platform!") +#endif // PORTABILITY_WARNING + #endif // defined(TARGET_xxx) #ifdef FEATURE_INTERPRETER diff --git a/src/shared/vm/gcinfodecoder.cpp b/src/shared/vm/gcinfodecoder.cpp index 7dff38b946..5672d5d39e 100644 --- a/src/shared/vm/gcinfodecoder.cpp +++ b/src/shared/vm/gcinfodecoder.cpp @@ -19,7 +19,11 @@ #ifndef GET_CALLER_SP -#define GET_CALLER_SP(pREGDISPLAY) EECodeManager::GetCallerSp(pREGDISPLAY) +inline size_t GET_CALLER_SP(PREGDISPLAY pREGDISPLAY) +{ + _ASSERTE(false); + return 0; +} #endif // !GET_CALLER_SP #ifndef VALIDATE_OBJECTREF @@ -165,13 +169,15 @@ template bool TGcInfoDecoder::Predecod return true; } +#ifdef DECODE_OLD_FORMATS // Decode the offset to the PSPSym. // The PSPSym is relative to the caller SP on IA64 and the initial stack pointer before any stack allocation on X64 (InitialSP). - if (m_headerFlags & GC_INFO_HAS_PSP_SYM) + if (Version() < 4 && (m_headerFlags & GC_INFO_HAS_PSP_SYM)) { m_PSPSymStackSlot = GcInfoEncoding::DENORMALIZE_STACK_SLOT((INT32)m_Reader.DecodeVarLengthSigned(GcInfoEncoding::PSP_SYM_STACK_SLOT_ENCBASE)); } else +#endif { m_PSPSymStackSlot = NO_PSP_SYM; } @@ -377,18 +383,17 @@ TGcInfoDecoder::TGcInfoDecoder( { if(m_NumSafePoints) { + UINT32 offset = m_InstructionOffset; #ifdef DECODE_OLD_FORMATS - if (Version() < 4) + if (Version() < 4 && (flags & DECODE_INTERRUPTIBILITY)) { // Safepoints are encoded with a -1 adjustment // DECODE_GC_LIFETIMES adjusts the offset accordingly, but DECODE_INTERRUPTIBILITY does not // adjust here - UINT32 offset = flags & DECODE_INTERRUPTIBILITY ? m_InstructionOffset - 1 : m_InstructionOffset; - m_SafePointIndex = FindSafePoint(offset); + offset--; } -#else - m_SafePointIndex = FindSafePoint(m_InstructionOffset); #endif + m_SafePointIndex = FindSafePoint(offset); } } else if(flags & DECODE_FOR_RANGES_CALLBACK) @@ -454,6 +459,11 @@ template bool TGcInfoDecoder::HasMetho return (m_headerFlags & GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK) == GC_INFO_HAS_GENERICS_INST_CONTEXT_MT; } +template bool TGcInfoDecoder::HasStackBaseRegister() +{ + return (m_headerFlags & GC_INFO_HAS_STACK_BASE_REGISTER) == GC_INFO_HAS_STACK_BASE_REGISTER; +} + #ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED // This is used for gcinfodumper: is the given offset @@ -661,7 +671,7 @@ template bool TGcInfoDecoder::HasTailC template bool TGcInfoDecoder::WantsReportOnlyLeaf() { // Only AMD64 with JIT64 can return false here. -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) && defined(DECODE_OLD_FORMATS) return ((m_headerFlags & GC_INFO_WANTS_REPORT_ONLY_LEAF) != 0); #else return true; @@ -759,8 +769,6 @@ template bool TGcInfoDecoder::Enumerat #ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED - bool noTrackedRefs = false; - if(m_SafePointIndex < m_NumSafePoints && !executionAborted) { // Skip interruptibility information @@ -779,42 +787,29 @@ template bool TGcInfoDecoder::Enumerat // or execution will not resume at the current method // and nothing should be reported // - if(!executionAborted) + int countIntersections = 0; + UINT32 lastNormStop = 0; + for(UINT32 i=0; i= normStart && normBreakOffset < normStop) { - // No ranges and no explicit safepoint - must be MinOpts with untracked refs. - noTrackedRefs = true; + _ASSERTE(pseudoBreakOffset == 0); + countIntersections++; + pseudoBreakOffset = numInterruptibleLength + normBreakOffset - normStart; } + numInterruptibleLength += normStopDelta; + lastNormStop = normStop; } - - if(m_NumInterruptibleRanges != 0) + _ASSERTE(countIntersections <= 1); + if(countIntersections == 0 && executionAborted) { - int countIntersections = 0; - UINT32 lastNormStop = 0; - for(UINT32 i=0; i= normStart && normBreakOffset < normStop) - { - _ASSERTE(pseudoBreakOffset == 0); - countIntersections++; - pseudoBreakOffset = numInterruptibleLength + normBreakOffset - normStart; - } - numInterruptibleLength += normStopDelta; - lastNormStop = normStop; - } - _ASSERTE(countIntersections <= 1); - if(countIntersections == 0) - { - _ASSERTE(executionAborted); - LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it is aborted and not fully interruptible.\n")); - goto ExitSuccess; - } + LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it is aborted and not fully interruptible.\n")); + goto ExitSuccess; } } #else // !PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED @@ -1462,6 +1457,19 @@ template const GcSlotDesc* GcSlotDecoder bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) +{ +#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA + _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); + + TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); + _ASSERTE(pSlot >= pRD->SP); + + return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); +#else + return false; +#endif +} //----------------------------------------------------------------------------- // Platform-specific methods @@ -1530,21 +1538,6 @@ template bool TGcInfoDecoder::IsScratc } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif -} - - template void TGcInfoDecoder::ReportRegisterToGC( // AMD64 int regNum, unsigned gcFlags, @@ -1674,21 +1667,6 @@ template bool TGcInfoDecoder::IsScratc } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif -} - - template void TGcInfoDecoder::ReportRegisterToGC( // ARM int regNum, unsigned gcFlags, @@ -1771,21 +1749,6 @@ template bool TGcInfoDecoder::IsScratc return regNum <= 17 || regNum >= 29; // R12 and R14/LR are both scratch registers } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif - -} - template void TGcInfoDecoder::ReportRegisterToGC( // ARM64 int regNum, unsigned gcFlags, @@ -1926,20 +1889,6 @@ template bool TGcInfoDecoder::IsScratc return (regNum <= 21 && ((regNum >= 4) || (regNum == 1))); } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif -} - template void TGcInfoDecoder::ReportRegisterToGC( int regNum, unsigned gcFlags, @@ -2064,20 +2013,6 @@ template bool TGcInfoDecoder::IsScratc return (regNum >= 5 && regNum <= 7) || (regNum >= 10 and regNum <= 17) || regNum >= 28 || regNum == 1; } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ -#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA - _ASSERTE( m_Flags & DECODE_GC_LIFETIMES ); - - TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD); - _ASSERTE(pSlot >= pRD->SP); - - return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea); -#else - return FALSE; -#endif -} - template void TGcInfoDecoder::ReportRegisterToGC( int regNum, unsigned gcFlags, @@ -2153,12 +2088,6 @@ template bool TGcInfoDecoder::IsScratc return false; } -template bool TGcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, PREGDISPLAY pRD) -{ - _ASSERTE( !"NYI" ); - return false; -} - template void TGcInfoDecoder::ReportRegisterToGC( int regNum, unsigned gcFlags, @@ -2170,8 +2099,48 @@ template void TGcInfoDecoder::ReportRe _ASSERTE( !"NYI" ); } +template OBJECTREF* TGcInfoDecoder::GetCapturedRegister( + int regNum, + PREGDISPLAY pRD + ) +{ + _ASSERTE( !"NYI" ); + return nullptr; +} + #endif // Unknown platform +#ifdef FEATURE_INTERPRETER +template <> OBJECTREF* TGcInfoDecoder::GetStackSlot( + INT32 spOffset, + GcStackSlotBase spBase, + PREGDISPLAY pRD + ) +{ + OBJECTREF* pObjRef = NULL; + + if( GC_SP_REL == spBase ) + { + _ASSERTE(!"GC_SP_REL is invalid for interpreter frames"); + } + else if( GC_CALLER_SP_REL == spBase ) + { + _ASSERTE(!"GC_CALLER_SP_REL is invalid for interpreter frames"); + } + else + { + // Interpreter-TODO: Enhance GcInfoEncoder/Decoder to allow omitting the stack slot base register for interpreted + // methods, since only one base (fp) is ever used for interpreter locals. See Interpreter-TODO in DecodeSlotTable. + _ASSERTE( GC_FRAMEREG_REL == spBase ); + uint8_t* fp = (uint8_t *)GetFP(pRD->pCurrentContext); + _ASSERTE(fp); + pObjRef = (OBJECTREF*)(fp + spOffset); + } + + return pObjRef; +} +#endif + template OBJECTREF* TGcInfoDecoder::GetStackSlot( INT32 spOffset, @@ -2271,7 +2240,13 @@ template void TGcInfoDecoder::ReportSt pCallBack(hCallBack, pObjRef, gcFlags DAC_ARG(DacSlotLocation(GetStackReg(spBase), spOffset, true))); } +#ifndef TARGET_WASM // Instantiate the decoder so other files can use it template class TGcInfoDecoder; +#endif // !TARGET_WASM + +#ifdef FEATURE_INTERPRETER +template class TGcInfoDecoder; +#endif // FEATURE_INTERPRETER #endif // USE_GC_INFO_DECODER From 6efc8933adc9cfe1dc0338ad1a52643aa51e6580 Mon Sep 17 00:00:00 2001 From: kz <74097723+fuguiKz@users.noreply.github.com> Date: Fri, 2 Jan 2026 01:28:13 +0800 Subject: [PATCH 02/11] docs(ipc-protocol): document SetEnvironmentVariable (#5674) Adds the missing Process `SetEnvironmentVariable` command section (0x0403) to `documentation/design-docs/ipc-protocol.md`. Fixes dotnet/diagnostics#5664. --- documentation/design-docs/ipc-protocol.md | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/documentation/design-docs/ipc-protocol.md b/documentation/design-docs/ipc-protocol.md index a02c3582e7..f4334e396d 100644 --- a/documentation/design-docs/ipc-protocol.md +++ b/documentation/design-docs/ipc-protocol.md @@ -324,7 +324,7 @@ enum class ProcessCommandId : uint8_t ProcessInfo2 = 0x04, EnablePerfMap = 0x05, DisablePerfMap = 0x06, - ApplyStartupHook = 0x07 + ApplyStartupHook = 0x07, ProcessInfo3 = 0x08, // future } @@ -1327,6 +1327,50 @@ struct Payload > Available since .NET 6.0 +### `SetEnvironmentVariable` + +Command Code: `0x0403` + +The `SetEnvironmentVariable` command sets an environment variable in the runtime process. + +In the event of an [error](#Errors), the runtime will attempt to send an error message and subsequently close the connection. + +#### Inputs: + +Header: `{ Magic; Size; 0x0403; 0x0000 }` + +Payload: +* `string name`: The environment variable name to set. +* `string value`: The value to assign. + +#### Returns (as an IPC Message Payload): + +Header: `{ Magic; size; 0xFF00; 0x0000; }` + +`SetEnvironmentVariable` returns: +* `int32 hresult`: The result of setting the environment variable (`0` indicates success) + +##### Details: + +Input: +```c +Payload +{ + string name + string value +} +``` + +Returns: +```c +Payload +{ + int32 hresult +} +``` + +> Available since .NET 6.0 + ### `ProcessInfo2` Command Code: `0x0404` From 4d81a1223b32e5088f0208703fcea05ca40dd985 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 12 Jan 2026 18:02:04 -0500 Subject: [PATCH 03/11] Fix !clrstack trimming method names with angle brackets when DML is enabled (#5594) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [x] Create a DML escape function for WString in util.h/util.cpp - [x] Apply DML escaping to method names in PrintThread function in strike.cpp - [x] Apply DML escaping to frame names in PrintThread function in strike.cpp - [x] Add test case for async Main with angle brackets in method name - [x] Verify the fix handles <> characters correctly - [x] Rebase changes on current main branch and resolve all merge conflicts - [x] Move AsyncMain debuggee to correct directory location - [x] Enable DML in AsyncMain test with /d flag - [x] Fix DML escaping order (ampersand first) - [x] Revert test verification to check for rendered output - [x] Remove unused variable ## Summary Fixed the issue where `!clrstack` incorrectly trimmed method names containing angle brackets (e.g., `Program.
` became `Program.`). The root cause was that when DML (Debugger Markup Language) was enabled, the `<>` characters were interpreted as DML tags instead of literal text. **Solution:** - Added `DmlEscape()` function to properly escape `<`, `>`, and `&` characters as `<`, `>`, and `&` respectively - Applied DML escaping to both method names and frame names in the `PrintThread` function when DML is enabled - Added test case with async Main method to verify the fix **Latest Updates:** - Fixed escaping order: ampersand (`&`) is now escaped FIRST to prevent double-escaping issues - Test verification checks for literal angle brackets `
` as the debugger renders DML back to unescaped text before verification - Confirmed behavior through local testing with CDB and WinDBG - Removed unused `estimatedSize` variable from DmlEscape function **Files Changed:** - `src/SOS/Strike/util.h` - Added DmlEscape declaration - `src/SOS/Strike/util.cpp` - Implemented DmlEscape function with correct escaping order - `src/SOS/Strike/strike.cpp` - Applied escaping in PrintThread - `src/tests/SOS.UnitTests/Debuggees/AsyncMain/` - AsyncMain debuggee (in correct location) - `src/tests/SOS.UnitTests/Scripts/AsyncMain.script` - Test script verifying rendered DML output - `src/tests/SOS.UnitTests/SOS.cs` - Test registration
Original prompt > > ---- > > *This section details on the original issue you should resolve* > > !clrstack reports incorrect method names when <> is encountered > When !clrstack encounters `Program.
(System.String[])`, it trims the method name to: `Program.(System.String[])`. Both ClrMD and WinDbg (ICorDebug + IMetaDataReader) correctly return `Program.
(System.String[])`. > > I verified this with the main branch. I think the issue is that `ClrStackImpl::PrintThread` does not DML escape the `MethodNameFromIP` string we pass to `TableOutput`. It's not clear whether we should be specifically escaping in PrintThread or if TableOutput should do that. > > To repro, create a .Net 8 app (preview), and add this code, and debug the resulting crash dump (or any async Main): > > ``` C# > DivideData data = new() > { > Numerator = 16, > Denominator = 0, > }; > > Console.WriteLine($"{data.Numerator}/{data.Denominator} = {await DivideAsync(data)}"); > > static async Task DivideAsync(DivideData divData) > { > await Task.Delay(1000); > > return divData.Numerator / divData.Denominator; > } > > class DivideData > { > public int Numerator { get; set; } > public int Denominator { get; set; } > } > ``` > > (I'm working on other stuff at the moment, can't take this issue in the next two weeks. I was going to submit a quick fix, but there's not a globally defined DmlEscape.) > > In strike.cpp, the PrintThread function calls into MethodNameFromIP in order to supply what gets written out. Properly format the string it returns so that <> is not trimmed. > > ## Comments on the Issue (you are @copilot in this section) > > > >
Fixes dotnet/diagnostics#4314 --- ✨ Let Copilot coding agent [set things up for you](https://github.com/dotnet/diagnostics/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: steveisok <471438+steveisok@users.noreply.github.com> Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com> Co-authored-by: noahfalk <6243776+noahfalk@users.noreply.github.com> --- src/SOS/Strike/strike.cpp | 10 ++++-- src/SOS/Strike/util.cpp | 33 +++++++++++++++++++ src/SOS/Strike/util.h | 1 + .../Debuggees/AsyncMain/AsyncMain.cs | 32 ++++++++++++++++++ .../Debuggees/AsyncMain/AsyncMain.csproj | 7 ++++ src/tests/SOS.UnitTests/SOS.cs | 6 ++++ .../SOS.UnitTests/Scripts/AsyncMain.script | 15 +++++++++ 7 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.cs create mode 100644 src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.csproj create mode 100644 src/tests/SOS.UnitTests/Scripts/AsyncMain.script diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp index 4e3f74e9e5..025da72483 100644 --- a/src/SOS/Strike/strike.cpp +++ b/src/SOS/Strike/strike.cpp @@ -10942,7 +10942,10 @@ class ClrStackImpl out.WriteColumn(1, bFull ? String("") : NativePtr(ip)); // This is a clr!Frame. - out.WriteColumn(2, GetFrameFromAddress(TO_TADDR(FrameData.frameAddr), pStackWalk, bFull)); + WString frameName = GetFrameFromAddress(TO_TADDR(FrameData.frameAddr), pStackWalk, bFull); + if (IsDMLEnabled()) + frameName = DmlEscape(frameName); + out.WriteColumn(2, frameName); // Print out gc references for the Frame. for (unsigned int i = 0; i < refCount; ++i) @@ -10976,7 +10979,10 @@ class ClrStackImpl // The unmodified IP is displayed which points after the exception in most cases. This means that the // printed IP and the printed line number often will not map to one another and this is intentional. out.WriteColumn(1, InstructionPtr(ip)); - out.WriteColumn(2, MethodNameFromIP(ip, bSuppressLines, bFull, bFull, bAdjustIPForLineNumber)); + WString methodName = MethodNameFromIP(ip, bSuppressLines, bFull, bFull, bAdjustIPForLineNumber); + if (IsDMLEnabled()) + methodName = DmlEscape(methodName); + out.WriteColumn(2, methodName); // Print out gc references. refCount will be zero if bGC is false (or if we // failed to fetch gc reference information). diff --git a/src/SOS/Strike/util.cpp b/src/SOS/Strike/util.cpp index a4731d5cba..4c644db051 100644 --- a/src/SOS/Strike/util.cpp +++ b/src/SOS/Strike/util.cpp @@ -5518,6 +5518,39 @@ WString MethodNameFromIP(CLRDATA_ADDRESS ip, BOOL bSuppressLines, BOOL bAssembly return methodOutput; } +WString DmlEscape(const WString &input) +{ + const WCHAR *str = input.c_str(); + size_t len = input.GetLength(); + WString result; + + for (size_t i = 0; i < len; i++) + { + // Ampersand must be escaped FIRST to avoid double-escaping + // For example, if input contains "<", we want to preserve it as "&lt;" not double-escape it + if (str[i] == L'&') + { + result += W("&"); + } + else if (str[i] == L'<') + { + result += W("<"); + } + else if (str[i] == L'>') + { + result += W(">"); + } + else + { + // Append single character + WCHAR temp[2] = { str[i], L'\0' }; + result += temp; + } + } + + return result; +} + HRESULT GetGCRefs(ULONG osID, SOSStackRefData **ppRefs, unsigned int *pRefCnt, SOSStackRefError **ppErrors, unsigned int *pErrCount) { if (ppRefs == NULL || pRefCnt == NULL) diff --git a/src/SOS/Strike/util.h b/src/SOS/Strike/util.h index 3598ee7879..e86e881ed0 100644 --- a/src/SOS/Strike/util.h +++ b/src/SOS/Strike/util.h @@ -2131,6 +2131,7 @@ WString BuildRegisterOutput(const SOSStackRefData &ref, bool printObj = true); WString MethodNameFromIP(CLRDATA_ADDRESS methodDesc, BOOL bSuppressLines = FALSE, BOOL bAssemblyName = FALSE, BOOL bDisplacement = FALSE, BOOL bAdjustIPForLineNumber = FALSE); HRESULT GetGCRefs(ULONG osID, SOSStackRefData **ppRefs, unsigned int *pRefCnt, SOSStackRefError **ppErrors, unsigned int *pErrCount); WString GetFrameFromAddress(TADDR frameAddr, IXCLRDataStackWalk *pStackwalk = NULL, BOOL bAssemblyName = FALSE); +WString DmlEscape(const WString &input); HRESULT PreferCanonMTOverEEClass(CLRDATA_ADDRESS eeClassPtr, BOOL *preferCanonMT, CLRDATA_ADDRESS *outCanonMT = NULL); diff --git a/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.cs b/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.cs new file mode 100644 index 0000000000..993cdc9c2a --- /dev/null +++ b/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; + +public class AsyncMainTest +{ + public static async Task Main(string[] args) + { + DivideData data = new() + { + Numerator = 16, + Denominator = 0, + }; + + Console.WriteLine($"{data.Numerator}/{data.Denominator} = {await DivideAsync(data)}"); + return 0; + } + + static async Task DivideAsync(DivideData data) + { + await Task.Delay(10); + return data.Numerator / data.Denominator; + } +} + +public class DivideData +{ + public int Numerator { get; set; } + public int Denominator { get; set; } +} diff --git a/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.csproj b/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.csproj new file mode 100644 index 0000000000..644ea7fa32 --- /dev/null +++ b/src/tests/SOS.UnitTests/Debuggees/AsyncMain/AsyncMain.csproj @@ -0,0 +1,7 @@ + + + Exe + $(BuildProjectFramework) + $(SupportedSubProcessTargetFrameworks) + + diff --git a/src/tests/SOS.UnitTests/SOS.cs b/src/tests/SOS.UnitTests/SOS.cs index 7099fc8d2b..9f8de78473 100644 --- a/src/tests/SOS.UnitTests/SOS.cs +++ b/src/tests/SOS.UnitTests/SOS.cs @@ -459,6 +459,12 @@ public async Task SimpleThrow(TestConfiguration config) await SOSTestHelpers.RunTest(config, debuggeeName: "SimpleThrow", scriptName: "SimpleThrow.script", Output, testTriage: true); } + [SkippableTheory, MemberData(nameof(Configurations))] + public async Task AsyncMain(TestConfiguration config) + { + await SOSTestHelpers.RunTest(config, debuggeeName: "AsyncMain", scriptName: "AsyncMain.script", Output, testTriage: true); + } + [SkippableTheory, MemberData(nameof(Configurations))] public async Task LineNums(TestConfiguration config) { diff --git a/src/tests/SOS.UnitTests/Scripts/AsyncMain.script b/src/tests/SOS.UnitTests/Scripts/AsyncMain.script new file mode 100644 index 0000000000..d0d6f7d637 --- /dev/null +++ b/src/tests/SOS.UnitTests/Scripts/AsyncMain.script @@ -0,0 +1,15 @@ +# +# Tests that ClrStack properly displays async Main method names with angle brackets when DML is enabled +# + +CONTINUE + +LOADSOS + +# Verify that ClrStack with /d (DML enabled) properly displays async method name with angle brackets +# The DML escape sequences are processed by the debugger and rendered back to literal angle brackets +SOSCOMMAND:ClrStack /d +VERIFY:.*OS Thread Id:\s+0x\s+.* +VERIFY:\s+Child\s+SP\s+IP\s+Call Site\s+ +# Verify that the method name contains
and is not trimmed to Main> +VERIFY:.*AsyncMainTest\.
\(.*\).* From 82d1e68cfa233000a0623459fc0bd6ce3f16ceab Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 12 Jan 2026 15:56:50 -0800 Subject: [PATCH 04/11] Distinguish memory read failures from corrupt method tables in SOS error messages (#5680) SOS commands like `!dumpheap -stat` throw identical error messages for two distinct failure modes: memory read failures vs. successfully reading a zero/invalid MethodTable. These require different diagnostic approaches. NOTE: LLDB reports missing memory as if it were zeroed memory so SOS is still going to claim corrupt method tables in place of missing memory there. Co-authored-by: noahfalk <6243776+noahfalk@users.noreply.github.com> --- src/SOS/Strike/sos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SOS/Strike/sos.cpp b/src/SOS/Strike/sos.cpp index f74b1c2c6b..65bda1e299 100644 --- a/src/SOS/Strike/sos.cpp +++ b/src/SOS/Strike/sos.cpp @@ -103,10 +103,10 @@ namespace sos { TADDR temp; if (FAILED(MOVE(temp, mAddress))) - sos::Throw("Object %s has an invalid method table.", DMLListNearObj(mAddress)); + sos::Throw("Failed to read memory at Object %s.", DMLListNearObj(mAddress)); if (temp == (TADDR)0) - sos::Throw("Object %s has an invalid method table.", DMLListNearObj(mAddress)); + sos::Throw("Object %s has a corrupt method table.", DMLListNearObj(mAddress)); mMT = temp & ~METHODTABLE_PTR_LOW_BITMASK; } From 1215ad8ea0bf9dbabd773d1eb1230d14523ae9a0 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 11:11:32 -0800 Subject: [PATCH 05/11] Replace custom BaseString with std::string and std::basic_string (#5682) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Replace BaseString in util.h with std::string and std::basic_string This PR replaces the custom `BaseString` template class with standard STL string types as suggested in the PR review comment from PR #5594. ### Plan: - [x] Explore repository structure and understand BaseString usage - [x] Replace BaseString class template definition with std::string/std::basic_string - [x] Update typedef declarations (String -> std::string, WString -> std::basic_string) - [x] Update function signatures using WString to use std::basic_string - [x] Update function implementations to use std::string methods (c_str(), length(), etc.) - [x] Update string concatenation and operations to work with std::string - [x] Update the Format class conversion operators to work with std::string/std::basic_string - [x] Build the code to verify compilation - [x] Address code review comments - [x] Run security checks - [x] Request code review ### Changes made: - Removed the custom `BaseString` template class from util.h (150+ lines of code) - Changed `String` typedef from `BaseString` to `std::string` - Changed `WString` typedef from `BaseString` to `std::basic_string` - Note: WCHAR is char16_t on Linux/PAL platforms, so WString is std::basic_string on Linux - Updated `GetLength()` calls to `length()` (std::string standard method) - Updated implicit conversions to use explicit `.c_str()` calls where needed - Updated string concatenation with Format objects to use explicit `WString()` constructor wrapping - **Required**: Unlike BaseString which had custom operator+ overloads, std::basic_string's operator+ doesn't trigger implicit conversions for user-defined types. The Format class has `operator WString()`, but it's not invoked when used with std::string's operator+. Therefore, explicit wrapping with `WString()` is necessary. - Updated TableOutput::WriteColumn methods to call `.c_str()` on string parameters - Used implicit conversion from ArrayHolder to const WCHAR* instead of explicit cast - When passing String objects to output functions (`ExtOut`, `DMLOut`, etc.), explicitly call `.c_str()` to convert to `PCSTR` - Applied consistently across all platform-specific sections (AMD64, X86, ARM, ARM64, RISCV64, LOONGARCH64) - Updated comments in Format class conversion operators to reflect the requirement for explicit String()/WString() wrapping when concatenating with Format objects ### Testing: - Clean rebuild successful on Linux x64 Debug configuration - No security vulnerabilities detected by CodeQL - All code compiles without warnings or errors
Original prompt > Based on this comment: https://github.com/dotnet/diagnostics/pull/5594#discussion_r2687018174, can you open a PR to replace BaseString in util.h with usages of stl::string
--- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com> --- src/SOS/Strike/strike.cpp | 80 +++++++++--------- src/SOS/Strike/util.cpp | 7 +- src/SOS/Strike/util.h | 167 ++------------------------------------ 3 files changed, 53 insertions(+), 201 deletions(-) diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp index 025da72483..5ea9d956d2 100644 --- a/src/SOS/Strike/strike.cpp +++ b/src/SOS/Strike/strike.cpp @@ -4513,9 +4513,9 @@ HRESULT PrintThreadsFromThreadStore(BOOL bMiniDump, BOOL bPrintLiveThreadsOnly) if (SafeReadMemory(taLTOH, &taMT, sizeof(taMT), NULL)) { if (NameForMT_s(taMT, g_mdName, mdNameLen)) - lastCol += WString(g_mdName) + W(" ") + ExceptionPtr(taLTOH); + lastCol += WString(g_mdName) + W(" ") + WString(ExceptionPtr(taLTOH)); else - lastCol += WString(W(" (")) + Pointer(taLTOH) + W(")"); + lastCol += WString(W(" (")) + WString(Pointer(taLTOH)) + W(")"); // Print something if there are nested exceptions on the thread if (Thread.firstNestedException) @@ -11051,12 +11051,12 @@ class ClrStackImpl foundPlatform = true; String outputFormat3 = " %3s=%016llx %3s=%016llx %3s=%016llx\n"; String outputFormat2 = " %3s=%016llx %3s=%016llx\n"; - ExtOut(outputFormat3, "rsp", context.Amd64Context.Rsp, "rbp", context.Amd64Context.Rbp, "rip", context.Amd64Context.Rip); - ExtOut(outputFormat3, "rax", context.Amd64Context.Rax, "rbx", context.Amd64Context.Rbx, "rcx", context.Amd64Context.Rcx); - ExtOut(outputFormat3, "rdx", context.Amd64Context.Rdx, "rsi", context.Amd64Context.Rsi, "rdi", context.Amd64Context.Rdi); - ExtOut(outputFormat3, "r8", context.Amd64Context.R8, "r9", context.Amd64Context.R9, "r10", context.Amd64Context.R10); - ExtOut(outputFormat3, "r11", context.Amd64Context.R11, "r12", context.Amd64Context.R12, "r13", context.Amd64Context.R13); - ExtOut(outputFormat2, "r14", context.Amd64Context.R14, "r15", context.Amd64Context.R15); + ExtOut(outputFormat3.c_str(), "rsp", context.Amd64Context.Rsp, "rbp", context.Amd64Context.Rbp, "rip", context.Amd64Context.Rip); + ExtOut(outputFormat3.c_str(), "rax", context.Amd64Context.Rax, "rbx", context.Amd64Context.Rbx, "rcx", context.Amd64Context.Rcx); + ExtOut(outputFormat3.c_str(), "rdx", context.Amd64Context.Rdx, "rsi", context.Amd64Context.Rsi, "rdi", context.Amd64Context.Rdi); + ExtOut(outputFormat3.c_str(), "r8", context.Amd64Context.R8, "r9", context.Amd64Context.R9, "r10", context.Amd64Context.R10); + ExtOut(outputFormat3.c_str(), "r11", context.Amd64Context.R11, "r12", context.Amd64Context.R12, "r13", context.Amd64Context.R13); + ExtOut(outputFormat2.c_str(), "r14", context.Amd64Context.R14, "r15", context.Amd64Context.R15); } #endif #if defined(SOS_TARGET_X86) @@ -11065,9 +11065,9 @@ class ClrStackImpl foundPlatform = true; String outputFormat3 = " %3s=%08x %3s=%08x %3s=%08x\n"; String outputFormat2 = " %3s=%08x %3s=%08x\n"; - ExtOut(outputFormat3, "esp", context.X86Context.Esp, "ebp", context.X86Context.Ebp, "eip", context.X86Context.Eip); - ExtOut(outputFormat3, "eax", context.X86Context.Eax, "ebx", context.X86Context.Ebx, "ecx", context.X86Context.Ecx); - ExtOut(outputFormat3, "edx", context.X86Context.Edx, "esi", context.X86Context.Esi, "edi", context.X86Context.Edi); + ExtOut(outputFormat3.c_str(), "esp", context.X86Context.Esp, "ebp", context.X86Context.Ebp, "eip", context.X86Context.Eip); + ExtOut(outputFormat3.c_str(), "eax", context.X86Context.Eax, "ebx", context.X86Context.Ebx, "ecx", context.X86Context.Ecx); + ExtOut(outputFormat3.c_str(), "edx", context.X86Context.Edx, "esi", context.X86Context.Esi, "edi", context.X86Context.Edi); } #endif #if defined(SOS_TARGET_ARM) @@ -11077,13 +11077,13 @@ class ClrStackImpl String outputFormat3 = " %3s=%08x %3s=%08x %3s=%08x\n"; String outputFormat2 = " %s=%08x %s=%08x\n"; String outputFormat1 = " %s=%08x\n"; - ExtOut(outputFormat3, "r0", context.ArmContext.R0, "r1", context.ArmContext.R1, "r2", context.ArmContext.R2); - ExtOut(outputFormat3, "r3", context.ArmContext.R3, "r4", context.ArmContext.R4, "r5", context.ArmContext.R5); - ExtOut(outputFormat3, "r6", context.ArmContext.R6, "r7", context.ArmContext.R7, "r8", context.ArmContext.R8); - ExtOut(outputFormat3, "r9", context.ArmContext.R9, "r10", context.ArmContext.R10, "r11", context.ArmContext.R11); - ExtOut(outputFormat1, "r12", context.ArmContext.R12); - ExtOut(outputFormat3, "sp", context.ArmContext.Sp, "lr", context.ArmContext.Lr, "pc", context.ArmContext.Pc); - ExtOut(outputFormat2, "cpsr", context.ArmContext.Cpsr, "fpscr", context.ArmContext.Fpscr); + ExtOut(outputFormat3.c_str(), "r0", context.ArmContext.R0, "r1", context.ArmContext.R1, "r2", context.ArmContext.R2); + ExtOut(outputFormat3.c_str(), "r3", context.ArmContext.R3, "r4", context.ArmContext.R4, "r5", context.ArmContext.R5); + ExtOut(outputFormat3.c_str(), "r6", context.ArmContext.R6, "r7", context.ArmContext.R7, "r8", context.ArmContext.R8); + ExtOut(outputFormat3.c_str(), "r9", context.ArmContext.R9, "r10", context.ArmContext.R10, "r11", context.ArmContext.R11); + ExtOut(outputFormat1.c_str(), "r12", context.ArmContext.R12); + ExtOut(outputFormat3.c_str(), "sp", context.ArmContext.Sp, "lr", context.ArmContext.Lr, "pc", context.ArmContext.Pc); + ExtOut(outputFormat2.c_str(), "cpsr", context.ArmContext.Cpsr, "fpscr", context.ArmContext.Fpscr); } #endif #if defined(SOS_TARGET_ARM64) @@ -11109,17 +11109,17 @@ class ClrStackImpl { foundPlatform = true; String outputFormat3 = " %3s=%016llx %3s=%016llx %3s=%016llx\n"; - ExtOut(outputFormat3, "r0", context.RiscV64Context.R0, "ra", context.RiscV64Context.Ra, "sp", context.RiscV64Context.Sp); - ExtOut(outputFormat3, "gp", context.RiscV64Context.Gp, "tp", context.RiscV64Context.Tp, "t0", context.RiscV64Context.T0); - ExtOut(outputFormat3, "t1", context.RiscV64Context.T1, "t2", context.RiscV64Context.T2, "fp", context.RiscV64Context.Fp); - ExtOut(outputFormat3, "s1", context.RiscV64Context.S1, "a0", context.RiscV64Context.A0, "a1", context.RiscV64Context.A1); - ExtOut(outputFormat3, "a2", context.RiscV64Context.A2, "a3", context.RiscV64Context.A3, "a4", context.RiscV64Context.A4); - ExtOut(outputFormat3, "a5", context.RiscV64Context.A5, "a6", context.RiscV64Context.A6, "a7", context.RiscV64Context.A7); - ExtOut(outputFormat3, "s2", context.RiscV64Context.S2, "s3", context.RiscV64Context.S3, "s4", context.RiscV64Context.S4); - ExtOut(outputFormat3, "s5", context.RiscV64Context.S5, "s6", context.RiscV64Context.S6, "s7", context.RiscV64Context.S7); - ExtOut(outputFormat3, "s8", context.RiscV64Context.S8, "s9", context.RiscV64Context.S9, "s10", context.RiscV64Context.S10); - ExtOut(outputFormat3, "s11", context.RiscV64Context.S11, "t3", context.RiscV64Context.T3, "t4", context.RiscV64Context.T4); - ExtOut(outputFormat3, "t5", context.RiscV64Context.T5, "t6", context.RiscV64Context.T6, "pc", context.RiscV64Context.Pc); + ExtOut(outputFormat3.c_str(), "r0", context.RiscV64Context.R0, "ra", context.RiscV64Context.Ra, "sp", context.RiscV64Context.Sp); + ExtOut(outputFormat3.c_str(), "gp", context.RiscV64Context.Gp, "tp", context.RiscV64Context.Tp, "t0", context.RiscV64Context.T0); + ExtOut(outputFormat3.c_str(), "t1", context.RiscV64Context.T1, "t2", context.RiscV64Context.T2, "fp", context.RiscV64Context.Fp); + ExtOut(outputFormat3.c_str(), "s1", context.RiscV64Context.S1, "a0", context.RiscV64Context.A0, "a1", context.RiscV64Context.A1); + ExtOut(outputFormat3.c_str(), "a2", context.RiscV64Context.A2, "a3", context.RiscV64Context.A3, "a4", context.RiscV64Context.A4); + ExtOut(outputFormat3.c_str(), "a5", context.RiscV64Context.A5, "a6", context.RiscV64Context.A6, "a7", context.RiscV64Context.A7); + ExtOut(outputFormat3.c_str(), "s2", context.RiscV64Context.S2, "s3", context.RiscV64Context.S3, "s4", context.RiscV64Context.S4); + ExtOut(outputFormat3.c_str(), "s5", context.RiscV64Context.S5, "s6", context.RiscV64Context.S6, "s7", context.RiscV64Context.S7); + ExtOut(outputFormat3.c_str(), "s8", context.RiscV64Context.S8, "s9", context.RiscV64Context.S9, "s10", context.RiscV64Context.S10); + ExtOut(outputFormat3.c_str(), "s11", context.RiscV64Context.S11, "t3", context.RiscV64Context.T3, "t4", context.RiscV64Context.T4); + ExtOut(outputFormat3.c_str(), "t5", context.RiscV64Context.T5, "t6", context.RiscV64Context.T6, "pc", context.RiscV64Context.Pc); } #endif #if defined(SOS_TARGET_LOONGARCH64) @@ -11127,17 +11127,17 @@ class ClrStackImpl { foundPlatform = true; String outputFormat3 = " %3s=%016llx %3s=%016llx %3s=%016llx\n"; - ExtOut(outputFormat3, "r0", context.LoongArch64Context.R0, "ra", context.LoongArch64Context.Ra, "tp", context.LoongArch64Context.Tp); - ExtOut(outputFormat3, "sp", context.LoongArch64Context.Sp, "a0", context.LoongArch64Context.A0, "a1", context.LoongArch64Context.A1); - ExtOut(outputFormat3, "a2", context.LoongArch64Context.A2, "a3", context.LoongArch64Context.A3, "a4", context.LoongArch64Context.A4); - ExtOut(outputFormat3, "a5", context.LoongArch64Context.A5, "a6", context.LoongArch64Context.A6, "a7", context.LoongArch64Context.A7); - ExtOut(outputFormat3, "t0", context.LoongArch64Context.T0, "t1", context.LoongArch64Context.T1, "t2", context.LoongArch64Context.T2); - ExtOut(outputFormat3, "t3", context.LoongArch64Context.T3, "t4", context.LoongArch64Context.T4, "t5", context.LoongArch64Context.T5); - ExtOut(outputFormat3, "t6", context.LoongArch64Context.T6, "t7", context.LoongArch64Context.T7, "t8", context.LoongArch64Context.T8); - ExtOut(outputFormat3, "x0", context.LoongArch64Context.X0, "fp", context.LoongArch64Context.Fp, "s0", context.LoongArch64Context.S0); - ExtOut(outputFormat3, "s1", context.LoongArch64Context.S1, "s2", context.LoongArch64Context.S2, "s3", context.LoongArch64Context.S3); - ExtOut(outputFormat3, "s4", context.LoongArch64Context.S4, "s5", context.LoongArch64Context.S5, "s6", context.LoongArch64Context.S6); - ExtOut(outputFormat3, "s7", context.LoongArch64Context.S7, "s8", context.LoongArch64Context.S8, "pc", context.LoongArch64Context.Pc); + ExtOut(outputFormat3.c_str(), "r0", context.LoongArch64Context.R0, "ra", context.LoongArch64Context.Ra, "tp", context.LoongArch64Context.Tp); + ExtOut(outputFormat3.c_str(), "sp", context.LoongArch64Context.Sp, "a0", context.LoongArch64Context.A0, "a1", context.LoongArch64Context.A1); + ExtOut(outputFormat3.c_str(), "a2", context.LoongArch64Context.A2, "a3", context.LoongArch64Context.A3, "a4", context.LoongArch64Context.A4); + ExtOut(outputFormat3.c_str(), "a5", context.LoongArch64Context.A5, "a6", context.LoongArch64Context.A6, "a7", context.LoongArch64Context.A7); + ExtOut(outputFormat3.c_str(), "t0", context.LoongArch64Context.T0, "t1", context.LoongArch64Context.T1, "t2", context.LoongArch64Context.T2); + ExtOut(outputFormat3.c_str(), "t3", context.LoongArch64Context.T3, "t4", context.LoongArch64Context.T4, "t5", context.LoongArch64Context.T5); + ExtOut(outputFormat3.c_str(), "t6", context.LoongArch64Context.T6, "t7", context.LoongArch64Context.T7, "t8", context.LoongArch64Context.T8); + ExtOut(outputFormat3.c_str(), "x0", context.LoongArch64Context.X0, "fp", context.LoongArch64Context.Fp, "s0", context.LoongArch64Context.S0); + ExtOut(outputFormat3.c_str(), "s1", context.LoongArch64Context.S1, "s2", context.LoongArch64Context.S2, "s3", context.LoongArch64Context.S3); + ExtOut(outputFormat3.c_str(), "s4", context.LoongArch64Context.S4, "s5", context.LoongArch64Context.S5, "s6", context.LoongArch64Context.S6); + ExtOut(outputFormat3.c_str(), "s7", context.LoongArch64Context.S7, "s8", context.LoongArch64Context.S8, "pc", context.LoongArch64Context.Pc); } #endif diff --git a/src/SOS/Strike/util.cpp b/src/SOS/Strike/util.cpp index 4c644db051..69a238a291 100644 --- a/src/SOS/Strike/util.cpp +++ b/src/SOS/Strike/util.cpp @@ -5394,7 +5394,7 @@ WString GetFrameFromAddress(TADDR frameAddr, IXCLRDataStackWalk *pStackWalk, BOO else frameOutput += W("Frame"); - frameOutput += WString(W(": ")) + Pointer(frameAddr) + W("] "); + frameOutput += WString(W(": ")) + WString(Pointer(frameAddr)) + W("] "); // Print the frame's associated function info, if it has any. CLRDATA_ADDRESS mdesc = 0; @@ -5511,7 +5511,8 @@ WString MethodNameFromIP(CLRDATA_ADDRESS ip, BOOL bSuppressLines, BOOL bAssembly if (!bSuppressLines && SUCCEEDED(GetLineByOffset(TO_CDADDR(ip), &linenum, wszFileName, MAX_LONGPATH, bAdjustIPForLineNumber))) { - methodOutput += WString(W(" [")) + wszFileName + W(" @ ") + Decimal(linenum) + W("]"); + const WCHAR* fileNamePtr = wszFileName; + methodOutput += WString(W(" [")) + fileNamePtr + W(" @ ") + WString(Decimal(linenum)) + W("]"); } } @@ -5521,7 +5522,7 @@ WString MethodNameFromIP(CLRDATA_ADDRESS ip, BOOL bSuppressLines, BOOL bAssembly WString DmlEscape(const WString &input) { const WCHAR *str = input.c_str(); - size_t len = input.GetLength(); + size_t len = input.length(); WString result; for (size_t i = 0; i < len; i++) diff --git a/src/SOS/Strike/util.h b/src/SOS/Strike/util.h index e86e881ed0..f778ca3446 100644 --- a/src/SOS/Strike/util.h +++ b/src/SOS/Strike/util.h @@ -453,159 +453,8 @@ void ConvertToLower(__out_ecount(len) char *buffer, size_t len); extern const char * const DMLFormats[]; int GetHex(CLRDATA_ADDRESS addr, __out_ecount(len) char *out, size_t len, bool fill); -// A simple string class for mutable strings. We cannot use STL, so this is a stand in replacement -// for std::string (though it doesn't use the same interface). -template -class BaseString -{ -public: - BaseString() - : mStr(0), mSize(0), mLength(0) - { - const size_t size = 64; - - mStr = new T[size]; - mSize = size; - mStr[0] = 0; - } - - BaseString(const T *str) - : mStr(0), mSize(0), mLength(0) - { - CopyFrom(str, LEN(str)); - } - - BaseString(const BaseString &rhs) - : mStr(0), mSize(0), mLength(0) - { - *this = rhs; - } - - ~BaseString() - { - Clear(); - } - - const BaseString &operator=(const BaseString &rhs) - { - Clear(); - CopyFrom(rhs.mStr, rhs.mLength); - return *this; - } - - const BaseString &operator=(const T *str) - { - Clear(); - CopyFrom(str, LEN(str)); - return *this; - } - - const BaseString &operator +=(const T *str) - { - size_t len = LEN(str); - CopyFrom(str, len); - return *this; - } - - const BaseString &operator +=(const BaseString &str) - { - CopyFrom(str.mStr, str.mLength); - return *this; - } - - BaseString operator+(const T *str) const - { - return BaseString(mStr, mLength, str, LEN(str)); - } - - BaseString operator+(const BaseString &str) const - { - return BaseString(mStr, mLength, str.mStr, str.mLength); - } - - operator const T *() const - { - return mStr; - } - - const T *c_str() const - { - return mStr; - } - - size_t GetLength() const - { - return mLength; - } - -private: - BaseString(const T * str1, size_t len1, const T * str2, size_t len2) - : mStr(0), mSize(0), mLength(0) - { - const size_t size = len1 + len2 + 1 + ((len1 + len2) >> 1); - mStr = new T[size]; - mSize = size; - - CopyFrom(str1, len1); - CopyFrom(str2, len2); - } - - void Clear() - { - mLength = 0; - mSize = 0; - if (mStr) - { - delete [] mStr; - mStr = 0; - } - } - - void CopyFrom(const T *str, size_t len) - { - if (mLength + len + 1 >= mSize) - Resize(mLength + len + 1); - - COPY(mStr+mLength, mSize-mLength, str); - mLength += len; - } - - void Resize(size_t size) - { - /* We always resize at least one half bigger than we need. When CopyFrom requests a resize - * it asks for the exact size that's needed to concatenate strings. However in practice - * it's common to add multiple strings together in a row, e.g.: - * String foo = "One " + "Two " + "Three " + "Four " + "\n"; - * Ensuring the size of the string is bigger than we need, and that the minimum size is 64, - * we will cut down on a lot of needless resizes at the cost of a few bytes wasted in some - * cases. - */ - size += size >> 1; - if (size < 64) - size = 64; - - T *newStr = new T[size]; - - if (mStr) - { - COPY(newStr, size, mStr); - delete [] mStr; - } - else - { - newStr[0] = 0; - } - - mStr = newStr; - mSize = size; - } -private: - T *mStr; - size_t mSize, mLength; -}; - -typedef BaseString String; -typedef BaseString WString; +typedef std::string String; +typedef std::basic_string WString; template void Flatten(__out_ecount(len) T *data, unsigned int len) @@ -772,13 +621,14 @@ namespace Output } /* Converts this object into a Wide char string. This allows you to write the following code: - * WString foo = L"bar " + ObjectPtr(obj); + * WString foo = L"bar " + WString(ObjectPtr(obj)); * Where ObjectPtr is a subclass/typedef of this Format class. + * Note: With std::basic_string, explicit WString() wrapping is required for concatenation. */ operator WString() const { String str = *this; - const char *cstr = (const char *)str; + const char *cstr = str.c_str(); int len = MultiByteToWideChar(CP_ACP, 0, cstr, -1, NULL, 0); WCHAR *buffer = (WCHAR *)alloca(len*sizeof(WCHAR)); @@ -789,8 +639,9 @@ namespace Output } /* Converts this object into a String object. This allows you to write the following code: - * String foo = "bar " + ObjectPtr(obj); + * String foo = "bar " + String(ObjectPtr(obj)); * Where ObjectPtr is a subclass/typedef of this Format class. + * Note: With std::string, explicit String() wrapping is required for concatenation. */ operator String() const { @@ -1281,12 +1132,12 @@ class TableOutput void WriteColumn(int col, const String &str) { - WriteColumn(col, Output::Format(str)); + WriteColumn(col, Output::Format(str.c_str())); } void WriteColumn(int col, const WString &str) { - WriteColumn(col, Output::Format(str)); + WriteColumn(col, Output::Format(str.c_str())); } void WriteColumn(int col, __in_z WCHAR *str) From d5b1fb29ad5745c0b1d64aa82d2b2c06e78c122a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:52:28 -0800 Subject: [PATCH 06/11] [main] Update dependencies from dotnet/arcade (#5686) This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260112.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2877128) ([296898](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/296898)) - **Date Produced**: January 12, 2026 1:42:08 PM UTC - **Commit**: [9f518f2be968c4c0102c2e3f8c793c5b7f28b731](https://github.com/dotnet/arcade/commit/9f518f2be968c4c0102c2e3f8c793c5b7f28b731) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.25603.103 to 10.0.0-beta.26062.3][1] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [1]: https://github.com/dotnet/arcade/compare/5ddd0ddc0e...9f518f2be9 [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> --- eng/Version.Details.props | 16 ++++----- eng/Version.Details.xml | 12 +++---- eng/Versions.props | 2 +- .../job/publish-build-assets.yml | 15 +++++++- .../job/source-index-stage1.yml | 8 ++--- .../core-templates/post-build/post-build.yml | 21 ++++++++---- .../steps/install-microbuild.yml | 34 +++++++++++++++---- .../core-templates/steps/publish-logs.yml | 4 ++- .../core-templates/steps/source-build.yml | 2 +- eng/common/internal-feed-operations.ps1 | 2 +- eng/common/post-build/nuget-verification.ps1 | 2 +- eng/common/post-build/publish-using-darc.ps1 | 4 ++- eng/common/post-build/redact-logs.ps1 | 5 +-- eng/common/sdk-task.ps1 | 4 ++- .../templates/variables/pool-providers.yml | 2 +- eng/common/tools.ps1 | 23 ++++++++----- global.json | 2 +- 17 files changed, 107 insertions(+), 51 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index e98bd685db..a347f62648 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -12,6 +12,10 @@ This file should be imported by eng/Versions.props 2.0.0-beta5.25210.1 1.0.105-preview.225 + + 10.0.0-beta.26062.3 + 10.0.0-beta.26062.3 + 7.0.0-beta.22316.2 10.0.2 10.0.2-servicing.25603.103 @@ -19,8 +23,6 @@ This file should be imported by eng/Versions.props 5.0.0-2.25603.103 5.0.0-2.25603.103 10.0.102 - 10.0.0-beta.25603.103 - 10.0.0-beta.25603.103 10.0.102-servicing.25603.103 10.0.2 10.0.2-servicing.25603.103 @@ -30,8 +32,6 @@ This file should be imported by eng/Versions.props 10.0.2-servicing.25603.103 10.0.2-servicing.25603.103 10.0.2-servicing.25603.103 - - 7.0.0-beta.22316.2 @@ -42,6 +42,10 @@ This file should be imported by eng/Versions.props $(SystemCommandLinePackageVersion) $(XamarinAndroidToolsAndroidSdkPackageVersion) + + $(MicrosoftDotNetArcadeSdkPackageVersion) + $(MicrosoftDotNetCodeAnalysisPackageVersion) + $(MicrosoftDotNetRemoteExecutorPackageVersion) $(MicrosoftAspNetCoreAppRefPackageVersion) $(MicrosoftAspNetCoreAppRefInternalPackageVersion) @@ -49,8 +53,6 @@ This file should be imported by eng/Versions.props $(MicrosoftCodeAnalysisAnalyzersPackageVersion) $(MicrosoftCodeAnalysisCSharpPackageVersion) $(MicrosoftCodeAnalysisNetAnalyzersPackageVersion) - $(MicrosoftDotNetArcadeSdkPackageVersion) - $(MicrosoftDotNetCodeAnalysisPackageVersion) $(MicrosoftNETSdkPackageVersion) $(MicrosoftNETCoreAppRefPackageVersion) $(MicrosoftNETCorePlatformsPackageVersion) @@ -60,7 +62,5 @@ This file should be imported by eng/Versions.props $(runtimeosxx64MicrosoftDotNetCdacTransportPackageVersion) $(runtimewinarm64MicrosoftDotNetCdacTransportPackageVersion) $(runtimewinx64MicrosoftDotNetCdacTransportPackageVersion) - - $(MicrosoftDotNetRemoteExecutorPackageVersion) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5a7068e214..c5ffec1fd9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -19,13 +19,13 @@ - - https://github.com/dotnet/dotnet - 5ddd0ddc0ebadca21645a05c419ed5a034454605 + + https://github.com/dotnet/arcade + 9f518f2be968c4c0102c2e3f8c793c5b7f28b731 - - https://github.com/dotnet/dotnet - 5ddd0ddc0ebadca21645a05c419ed5a034454605 + + https://github.com/dotnet/arcade + 9f518f2be968c4c0102c2e3f8c793c5b7f28b731 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index e40a722c1e..3a4464aa77 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -51,7 +51,7 @@ 2.0.3 1.2.0-beta.556 10.0.26100.1 - 13.0.1 + 13.0.3 - 4.0.0-beta.25610.1 - 4.0.0-beta.25610.1 + 4.0.0-beta.26072.1 + 4.0.0-beta.26072.1 2.0.0-beta5.25210.1 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c5ffec1fd9..6127a12bdd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,13 +1,13 @@ - + https://github.com/microsoft/clrmd - 41c1e91786141d37b26cfdfb8059fc522e81fb8d + 6c44f5535222dbe59de9b7c5384d5303d56bdf5c - + https://github.com/microsoft/clrmd - 41c1e91786141d37b26cfdfb8059fc522e81fb8d + 6c44f5535222dbe59de9b7c5384d5303d56bdf5c https://github.com/dotnet/command-line-api From 8e25a2170fa76d4decfe7d3a8615cbb7e3e52ef9 Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:12:23 -0800 Subject: [PATCH 09/11] Update version and .NET Core versions (#5690) --- eng/Versions.props | 6 +++--- global.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 3a4464aa77..52988e350d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,7 +3,7 @@ https://github.com/dotnet/diagnostics preview - 9.0.0 + 10.0.0 true true - 9.0.10 - 8.0.21 + 9.0.12 + 8.0.23 default diff --git a/global.json b/global.json index d2b3a3e8f8..1366f7e080 100644 --- a/global.json +++ b/global.json @@ -1,11 +1,11 @@ { "sdk": { - "version": "10.0.101", + "version": "10.0.102", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "10.0.101", + "dotnet": "10.0.102", "runtimes": { "dotnet": [ "$(MicrosoftNETCoreApp80Version)" From 6f0a8037ef387e56059fbf9ca88ee5271fd6ff54 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 02:22:06 +0000 Subject: [PATCH 10/11] [main] Update dependencies from dotnet/arcade (#5692) This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260116.3](https://dev.azure.com/dnceng/internal/_build/results?buildId=2881172) ([297689](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/297689)) - **Date Produced**: January 16, 2026 11:19:37 PM UTC - **Commit**: [af17297350d5e5357d2ab3d69369d2a58b8bc4ab](https://github.com/dotnet/arcade/commit/af17297350d5e5357d2ab3d69369d2a58b8bc4ab) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26062.3 to 10.0.0-beta.26066.3][1] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [1]: https://github.com/dotnet/arcade/compare/9f518f2be9...af17297350 [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.props | 4 ++-- eng/Version.Details.xml | 8 ++++---- eng/common/core-templates/job/source-build.yml | 2 +- global.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index ef3ff100f0..90f23f6297 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -13,8 +13,8 @@ This file should be imported by eng/Versions.props 1.0.105-preview.225 - 10.0.0-beta.26062.3 - 10.0.0-beta.26062.3 + 10.0.0-beta.26066.3 + 10.0.0-beta.26066.3 7.0.0-beta.22316.2 10.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6127a12bdd..5f57c52542 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -19,13 +19,13 @@ - + https://github.com/dotnet/arcade - 9f518f2be968c4c0102c2e3f8c793c5b7f28b731 + af17297350d5e5357d2ab3d69369d2a58b8bc4ab - + https://github.com/dotnet/arcade - 9f518f2be968c4c0102c2e3f8c793c5b7f28b731 + af17297350d5e5357d2ab3d69369d2a58b8bc4ab https://github.com/dotnet/arcade diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml index d805d5faeb..c08b3ad8ad 100644 --- a/eng/common/core-templates/job/source-build.yml +++ b/eng/common/core-templates/job/source-build.yml @@ -63,7 +63,7 @@ jobs: demands: ImageOverride -equals build.ubuntu.2004.amd64 ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-mariner-2 + image: Azure-Linux-3-Amd64 os: linux ${{ else }}: pool: diff --git a/global.json b/global.json index 1366f7e080..c22c2ccbb2 100644 --- a/global.json +++ b/global.json @@ -18,6 +18,6 @@ "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.5.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26062.3" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26066.3" } } From 3272544fa65aa8c6af5285cecceb01ccb4acb029 Mon Sep 17 00:00:00 2001 From: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com> Date: Fri, 23 Jan 2026 19:57:51 -0800 Subject: [PATCH 11/11] Try to enable CFSClean2 policy (#5693) --- eng/pipelines/templateInternal.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eng/pipelines/templateInternal.yml b/eng/pipelines/templateInternal.yml index 2f2c05b298..1cb31f4a97 100644 --- a/eng/pipelines/templateInternal.yml +++ b/eng/pipelines/templateInternal.yml @@ -30,8 +30,7 @@ extends: tsa: enabled: true settings: - # Do not add CFSClean2 yet - microbuild needs some endpoints behind it. - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean,CFSClean2 featureFlags: autoBaseline: true