Skip to content

Commit

Permalink
Allow ` in hex strings (#4379)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
leculver authored Oct 31, 2023
1 parent c022813 commit 9e06d89
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 19 deletions.
9 changes: 8 additions & 1 deletion src/Microsoft.Diagnostics.DebugServices/CommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ protected void WriteLineError(string format, params object[] args)
/// <returns></returns>
protected bool TryParseAddress(string addressInHexa, out ulong address)
{
if (addressInHexa == null)
if (string.IsNullOrWhiteSpace(addressInHexa))
{
address = 0;
return false;
Expand All @@ -105,6 +105,13 @@ protected bool TryParseAddress(string addressInHexa, out ulong address)

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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,13 @@ private void ParseArguments()
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)
Expand Down
8 changes: 6 additions & 2 deletions src/Microsoft.Diagnostics.ExtensionCommands/EEHeapCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ public override void Invoke()
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)
Expand Down
14 changes: 2 additions & 12 deletions src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,9 @@ public HeapWithFilters(ClrHeap heap)
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ public override void Invoke()
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)
Expand Down

0 comments on commit 9e06d89

Please sign in to comment.