Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Aug 11, 2025

This PR implements configurable authentication for symbol servers in both PerfView and HeapDump.exe, addressing the need for flexible credential management while maintaining backward compatibility.

Key Changes

Command Line Authentication Configuration

Added /SymbolsAuth command line argument that allows users to specify which authentication methods to use:

# Use only interactive browser authentication (default)
PerfView.exe /SymbolsAuth:Interactive

# Use environment variables and Visual Studio credentials
PerfView.exe /SymbolsAuth:Environment,VisualStudio

# Use all available authentication methods
PerfView.exe /SymbolsAuth:Environment,AzureCli,VisualStudio,Interactive

Available authentication types:

  • Environment - Uses environment variables (e.g., AZURE_CLIENT_ID, AZURE_CLIENT_SECRET)
  • AzureCli - Uses Azure CLI cached credentials
  • VisualStudio - Uses Visual Studio cached credentials
  • Interactive - Uses interactive browser authentication (default)

Unified Authentication Across Components

Both PerfView and HeapDump.exe now use the same authentication configuration:

  • PerfView passes the /SymbolsAuth argument to HeapDump.exe when launching it
  • HeapDump.exe supports the same authentication types and parsing logic
  • Consistent credential chain building across both executables

Backward Compatible Default Behavior

By default, both applications use only InteractiveBrowserCredential(), maintaining the same user experience as before while allowing power users to configure additional authentication methods as needed.

Implementation Details

  • Created SymbolsAuthenticationType enum with [Flags] attribute for combining authentication methods
  • Added parsing logic via built-in command line enum support for PerfView
  • Implemented custom parsing logic for HeapDump.exe
  • Modified credential chain construction to build credentials based on user-specified flags
  • Maintains all existing authentication behavior without UI changes

This approach provides flexibility for automated scenarios and enterprise environments while keeping the default experience simple for interactive users.

Fixes #2277.


💡 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 in the docs.

Copy link
Contributor Author

Copilot AI commented Aug 11, 2025

@brianrob 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement Symbol Server Authentication Improvements Implement Symbol Server Authentication Improvements Aug 11, 2025
Copilot AI requested a review from brianrob August 11, 2025 18:22
private static ChainedTokenCredential CreateTokenCredential()
{
return new ChainedTokenCredential(
new EnvironmentCredential(),
Copy link
Member

Choose a reason for hiding this comment

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

Rather than chaining all of these together, let's do the following. By default, let's set this to be an Interactive credential and nothing else. Then, if the user wants to override this, they can do so by specifying one or more credential types from the list of valid credentials on the command line, using a new command line argument that I'd like you to implement called /SymbolsAuth. Use an enum with flags to back the set of valid values based on what is currently supported by TokenCredential.

Copy link
Member

Choose a reason for hiding this comment

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

@copilot can you help with this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've implemented the requested changes:

  1. Reverted CreateTokenCredential() to use only InteractiveBrowserCredential() by default
  2. Added /SymbolsAuth command line argument that accepts comma-separated values: Environment, AzureCli, VisualStudio, Interactive
  3. Created SymbolsAuthenticationTypes enum with flags to represent the different credential types
  4. Updated the credential chain logic to build credentials based on the specified flags

The implementation allows users to specify multiple authentication types like:

  • /SymbolsAuth:Environment,VisualStudio
  • /SymbolsAuth:Interactive (default behavior)
  • /SymbolsAuth:Environment,AzureCli,VisualStudio,Interactive (equivalent to previous chained approach)

Changes made in commit 47a3b2e

…tial types

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI changed the title Implement Symbol Server Authentication Improvements Implement configurable symbol server authentication with /SymbolsAuth command line argument Aug 11, 2025
Copilot AI requested a review from brianrob August 11, 2025 20:06
// options common to multiple commands
public string DataFile; // This is the name of the ETL file (not the ZIP file)
public string LogFile;
public string SymbolsAuth; // Specifies authentication types for symbol servers (comma-separated)
Copy link
Member

@brianrob brianrob Aug 11, 2025

Choose a reason for hiding this comment

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

@copilot, Rather than using a string and having to parse it, you can use the enum directly and even set the default value to be Interactive here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use SymbolsAuthenticationType enum directly with default value Interactive in commit 52c1162. The command line parser's built-in enum support handles parsing and validation automatically.

/// </summary>
/// <param name="symbolsAuthArg">Comma-separated string of authentication types</param>
/// <returns>Combined flags representing the specified authentication types</returns>
public static SymbolsAuthenticationTypes ParseSymbolsAuthenticationTypes(string symbolsAuthArg)
Copy link
Member

@brianrob brianrob Aug 11, 2025

Choose a reason for hiding this comment

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

@copilot, If the parser uses the enum directly, this method is no longer needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the ParseSymbolsAuthenticationTypes method in commit 52c1162 since the command line parser handles enum parsing directly.

/// Flags enum representing the types of Azure credentials that can be used for symbol authentication.
/// </summary>
[Flags]
public enum SymbolsAuthenticationTypes
Copy link
Member

@brianrob brianrob Aug 11, 2025

Choose a reason for hiding this comment

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

@copilot, Please rename this SymbolsAuthenticationType.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to SymbolsAuthenticationType (singular) in commit 52c1162.

@brianrob
Copy link
Member

@copilot, please see the latest review.

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI requested a review from brianrob August 11, 2025 20:21
Copy link
Member

@brianrob brianrob left a comment

Choose a reason for hiding this comment

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

@copilot Please address this request.

StatusBar.Log("Finished Lookup up symbols for " + moduleName + " Elapsed Time = " +
StatusBar.Duration.TotalSeconds.ToString("n3"));
}
catch (Azure.Identity.AuthenticationFailedException ex)
Copy link
Member

Choose a reason for hiding this comment

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

Please undo the dialog changes. This doesn't work and my local attempts to make this work were much more complicated than I thought. Additionally, it creates a bunch of behavior changes for SymbolReader.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Dialog changes have been removed from StackWindow.xaml.cs in commit 96e1083. All authentication failure handling, the ShowAuthenticationFailureDialog method, and the Azure.Identity using statement have been reverted to preserve the original SymbolReader behavior.

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI requested a review from brianrob August 11, 2025 21:50
Copy link
Member

@brianrob brianrob left a comment

Choose a reason for hiding this comment

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

@copilot please address this comment.

=> httpHandler.AddHandler(new BasicHttpAuthHandler(log));

private static ChainedTokenCredential CreateTokenCredential()
private static ChainedTokenCredential CreateTokenCredential(SymbolsAuthenticationType authTypes)
Copy link
Member

Choose a reason for hiding this comment

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

This same logic should also apply to the TokenCredential created in heapdump. I suspect you'll need to take the argument passed to PerfView and pass it to heapdump.exe and have heapdump.exe consume it in the same way that PerfView does here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've implemented the SymbolsAuth configuration for HeapDump.exe as requested. The changes include:

  1. HeapDump.exe now supports /SymbolsAuth argument - Added parsing logic and credential chain building identical to PerfView
  2. PerfView passes SymbolsAuth to HeapDump.exe - Modified HeapSnapshot.cs to include the /SymbolsAuth parameter when launching HeapDump.exe
  3. Maintains backward compatibility - HeapDump.exe defaults to Interactive authentication when no argument is provided

The implementation ensures that both PerfView and HeapDump.exe use the same authentication configuration specified by the user. Changes made in commit 5f0b8c5.

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI changed the title Implement configurable symbol server authentication with /SymbolsAuth command line argument Implement configurable symbol server authentication with /SymbolsAuth command line argument for PerfView and HeapDump Aug 11, 2025
Copilot AI requested a review from brianrob August 11, 2025 22:09
@brianrob brianrob marked this pull request as ready for review August 12, 2025 19:01
Copy link
Collaborator

@marklio marklio left a comment

Choose a reason for hiding this comment

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

This looks fine overall, just a few pieces of feedback.

/// <summary>
/// The token credential to use for symbol server authentication.
/// </summary>
public TokenCredential SymbolsAuthTokenCredential;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems strange to have both a public constructor arg AND a public settable field. My preferred approach if you need to provide this for consumption would be (in order of preference):

  • An internal get-only property
  • A public get-only property (if it really needs to be public)

Copy link
Collaborator

Choose a reason for hiding this comment

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

public fields are typically thought of as an anti-pattern

Copy link
Member

Choose a reason for hiding this comment

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

You're right - The constructor really doesn't need the argument anymore, especially with a default NULL value. I've removed it. One thing to note is that the GCHeapDumper class is part of HeapDump which isn't publicly shipped as surface area that folks can depend upon. It's really an internal implementation detail of PerfView, and so I imagine that's why it uses public fields. I can change this if you're feeling strongly about this, but for the purposes of this change, I'm just following the existing pattern.

Copy link
Collaborator

Choose a reason for hiding this comment

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

following existing pattern seems fine. I didn't notice the pattern.

else
{
Console.WriteLine("Invalid value for /SymbolsAuth: {0}", authTypesStr);
Console.WriteLine("Valid values are: Environment, AzureCli, VisualStudio, Interactive (can be combined with commas)");
Copy link
Collaborator

Choose a reason for hiding this comment

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

CONSIDER: generating this list from the enum

else if (arg.StartsWith("/SymbolsAuth:", StringComparison.OrdinalIgnoreCase))
{
string authTypesStr = arg.Substring(13);
if (TryParseSymbolsAuthenticationTypes(authTypesStr, out var parsedAuthTypes))
Copy link
Collaborator

@marklio marklio Aug 12, 2025

Choose a reason for hiding this comment

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

Why not pass symbolsAuth rather than introducing a new local? In all continuing cases, symbolsAuth is immediately overwritten with this value anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for pointing this out. That was just a bit odd (from copilot).

/// Flags enum representing the types of Azure credentials that can be used for symbol authentication.
/// </summary>
[Flags]
public enum SymbolsAuthenticationType
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems duplicative

Copy link
Collaborator

Choose a reason for hiding this comment

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

oh, this is actually another project

Copy link
Member

Choose a reason for hiding this comment

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

It is another project, but you're right. I merged these into one enum definition.

Copy link
Collaborator

@marklio marklio left a comment

Choose a reason for hiding this comment

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

looks good. Thanks for the context

@brianrob brianrob merged commit 45dfab9 into main Aug 13, 2025
5 checks passed
@brianrob brianrob deleted the copilot/fix-2277 branch August 13, 2025 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Symbol Server Authentication Improvements

3 participants