From: Lee Culver Date: Tue, 31 Oct 2023 22:26:48 +0000 (-0700) Subject: Allow ` in hex strings (#4379) X-Git-Tag: accepted/tizen/unified/20241231.014852~40^2~299 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9e06d89d6d51f361717c7ff5400f0af8d6d9ef69;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git Allow ` in hex strings (#4379) Update extension command parsing to allow a single \` in the middle of addresses. We allow "\`0123" because the user might have copied the \` marker in "0000\`0123". This makes commands more consistent since the C++ based SOS commands allow for \` in the addresses. Updated a location where we didn't use TryParseAddress but should have. Feature request from the GC team. --- diff --git a/src/Microsoft.Diagnostics.DebugServices/CommandBase.cs b/src/Microsoft.Diagnostics.DebugServices/CommandBase.cs index e843fd987..39c0508fa 100644 --- a/src/Microsoft.Diagnostics.DebugServices/CommandBase.cs +++ b/src/Microsoft.Diagnostics.DebugServices/CommandBase.cs @@ -91,7 +91,7 @@ namespace Microsoft.Diagnostics.DebugServices /// protected bool TryParseAddress(string addressInHexa, out ulong address) { - if (addressInHexa == null) + if (string.IsNullOrWhiteSpace(addressInHexa)) { address = 0; return false; @@ -105,6 +105,13 @@ namespace Microsoft.Diagnostics.DebugServices addressInHexa = addressInHexa.TrimStart('0'); + int index = addressInHexa.IndexOf('`'); + if (index >= 0 && index < addressInHexa.Length - 1) + { + // Remove up to one instance of ` since that's what WinDbg adds to its x64 addresses. + addressInHexa = addressInHexa.Substring(0, index) + addressInHexa.Substring(index + 1); + } + return ulong.TryParse(addressInHexa, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out address); } diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs index da718cf8d..d23e68e5b 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs @@ -197,9 +197,13 @@ namespace Microsoft.Diagnostics.ExtensionCommands FilteredHeap.GCHeap = GCHeap; } - if (!string.IsNullOrWhiteSpace(Segment)) + if (TryParseAddress(Segment, out ulong segment)) { - FilteredHeap.FilterBySegmentHex(Segment); + FilteredHeap.FilterBySegmentHex(segment); + } + else if (!string.IsNullOrWhiteSpace(Segment)) + { + throw new DiagnosticsException($"Failed to parse segment '{Segment}'."); } if (MemoryRange is not null && MemoryRange.Length > 0) diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/EEHeapCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/EEHeapCommand.cs index 59fb9fc3c..85daeabb6 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/EEHeapCommand.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/EEHeapCommand.cs @@ -54,9 +54,13 @@ namespace Microsoft.Diagnostics.ExtensionCommands HeapWithFilters.GCHeap = GCHeap; } - if (!string.IsNullOrWhiteSpace(Segment)) + if (TryParseAddress(Segment, out ulong segment)) { - HeapWithFilters.FilterBySegmentHex(Segment); + HeapWithFilters.FilterBySegmentHex(segment); + } + else if (!string.IsNullOrWhiteSpace(Segment)) + { + throw new DiagnosticsException($"Failed to parse segment '{Segment}'."); } if (MemoryRange is not null) diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs b/src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs index b8abc3778..36c229157 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs @@ -85,19 +85,9 @@ namespace Microsoft.Diagnostics.ExtensionCommands SortSubHeaps = (heap) => heap.OrderBy(heap => heap.Index); } - public void FilterBySegmentHex(string segmentStr) + public void FilterBySegmentHex(ulong segment) { - if (!ulong.TryParse(segmentStr, NumberStyles.HexNumber, null, out ulong segment)) - { - throw new ArgumentException($"Invalid segment address: {segmentStr}"); - } - - if (ThrowIfNoMatchingGCRegions && !_heap.Segments.Any(seg => seg.Address == segment || seg.CommittedMemory.Contains(segment))) - { - throw new ArgumentException($"No segments match address: {segment:x}"); - } - - Segment = segment; + Segment = segment != 0 ? segment : null; } public void FilterByStringMemoryRange(string[] memoryRange, string commandName) diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/VerifyHeapCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/VerifyHeapCommand.cs index 306403698..a7645b4d8 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/VerifyHeapCommand.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/VerifyHeapCommand.cs @@ -39,9 +39,13 @@ namespace Microsoft.Diagnostics.ExtensionCommands filteredHeap.GCHeap = GCHeap; } - if (!string.IsNullOrWhiteSpace(Segment)) + if (TryParseAddress(Segment, out ulong segment)) { - filteredHeap.FilterBySegmentHex(Segment); + filteredHeap.FilterBySegmentHex(segment); + } + else if (!string.IsNullOrWhiteSpace(Segment)) + { + throw new DiagnosticsException($"Failed to parse segment '{Segment}'."); } if (MemoryRange is not null)