This document provides standard guidance for AI agents and automated tools working on the .NET Diagnostics repository. Following these guidelines will help ensure consistency and quality across contributions.
The .NET Diagnostics repository contains diagnostic tools and libraries for .NET Core, including:
- SOS: The Son of Strike debugger extension
- dotnet-dump: Dump collection and analysis utility
- dotnet-gcdump: Heap analysis tool
- dotnet-trace: Event collection tool
- dotnet-counters: Performance counter monitoring tool
- Diagnostic libraries: Client libraries and services for diagnostics
The repository uses a cross-platform build system:
Linux/macOS:
./build.shWindows:
Build.cmd- Main build scripts:
build.sh/Build.cmdat repository root - Actual build logic:
eng/build.sh/eng/Build.cmd - Build configuration:
build.proj,Directory.Build.props,Directory.Build.targets
-configuration <Debug|Release>: Build configuration (default: Debug)-architecture <x64|x86|arm|arm64>: Target architecture-restore: Restore dependencies before building-build: Build the repository (incremental, only changed projects)-rebuild: Clean and rebuild (required after changing .props/.targets files)-bl: Requests a binlog.-test: Run tests after building
Understanding where build outputs are placed is essential for verification and debugging:
- Managed Build outputs:
artifacts/bin/<ProjectName>/<Configuration>/<TargetFramework>/ - SOS Build outputs:
artifacts/bin/<OS>.<Architecture>.<Configuration> - Test results when using global test script:
artifacts/TestResults/ - Build logs:
artifacts/log/(includingBuild.binlogfor detailed analysis) - NuGet packages:
artifacts/packages/<Configuration>/ - Temporary files:
artifacts/tmp/ - Intermediate files:
artifacts/obj/(such as obj files, generated files, etc.)
After a full build of the repo has been done, some commands can be used to iterate faster on changes:
# Build the relevant tool
dotnet build src/Tools/dotnet-dump/dotnet-dump.csproj
# Build without restoring (faster if dependencies haven't changed)
dotnet build --no-restore# Build the native components to verify compilation works
./build.sh -skipmanaged
# Do a full test run:
./build -testLinux/macOS:
./test.shWindows:
Test.cmdThe test script runs all tests in the repository. Important: test.sh calls eng/build.sh -test -skipmanaged -skipnative, which means it only runs tests without rebuilding. Always build first if you've made code changes.
Test projects are usually located in src/tests/ with the following structure:
- Tool and libraries tests:
*.UnitTests.csprojor*.Tests.csprojunder the appropriate tool's folder insrc/tests. - Changes with native dependencies (SOS, DBGShim, dotnet-sos, dotnet-dump) are better tested with the global test script.
# Run tests for a specific project
dotnet test src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/
# Run tests with detailed output
dotnet test --logger "console;verbosity=detailed"
# Run a specific test by name
dotnet test --filter "FullyQualifiedName~TestMethodName"/src
├── Microsoft.Diagnostics.DebugServices # Debug service interfaces
├── Microsoft.Diagnostics.DebugServices.Implementation # Debug service implementations
├── Microsoft.Diagnostics.ExtensionCommands # SOS extension commands
├── Microsoft.Diagnostics.Monitoring # Monitoring libraries
├── Microsoft.Diagnostics.NETCore.Client # Diagnostic client library
├── Microsoft.Diagnostics.Repl # REPL infrastructure
├── Microsoft.FileFormats # File format parsers
├── Microsoft.SymbolStore # Symbol store implementation
├── SOS # SOS debugger extension
├── Tools # Command-line tools (dump, trace, counters, gcdump)
├── tests # Test projects
└── shared # Shared native code
/documentation # Documentation files
/eng # Engineering/build infrastructure
The repository follows standard .NET coding conventions defined in the .editorconfig file at the root. This is a must for C# code. Ensure your changes conform to these settings:
- Indentation: 4 spaces (no tabs)
- Line endings: LF on Linux/macOS, CRLF on Windows (EditorConfig enforces this)
- Braces: Opening braces on new lines for types, methods, properties, control blocks
- Naming conventions (strictly enforced):
- PascalCase for types, methods, properties, public fields, constants
- camelCase for local variables and parameters
_camelCasefor private/internal instance fields (underscore prefix)s_camelCasefor static private/internal fields (s_ prefix)
- File headers: All C# files must include the MIT license header:
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license.
- Using directives: Must be placed outside the namespace declaration
- Var keyword: Avoid using
var- use explicit types (configured as error when type is apparent) - Additional rules:
- Trim trailing whitespace
- Insert final newline
- Prefer braces even for single-line blocks
Native code follows similar conventions:
- 4 spaces for indentation
- Braces on same line for control structures in C++
- Use clear, descriptive names
- Follow existing patterns in the codebase
Critical: Line endings must match the platform to avoid breaking scripts:
- Shell scripts (
.sh): LF only (will break on Linux/macOS if CRLF) - Batch files (
.cmd,.bat): CRLF only - C# files: LF on Linux/macOS, CRLF on Windows
- The
.editorconfigfile enforces these rules automatically
- Surgical changes: Make the smallest possible changes to address the issue. Focus on solving a single problem without addressing unrelated concerns. Balance minimal code changes with preserving overall code clarity and simplicity
- Preserve existing behavior: Don't break working functionality unless explicitly required
- Follow existing patterns: Match the style and structure of surrounding code
- Test thoroughly: Run builds and tests to verify changes
- Update documentation: If making significant changes, update relevant documentation
-
Run a clean build to ensure the current state is valid:
./build.sh # or Build.cmd on Windows -
Run tests to understand the baseline:
./test.sh # or Test.cmd on Windows -
Understand the area you're working on:
- Read related source files
- Review existing tests
- Check documentation in
/documentation
- Build: Ensure your changes compile without errors or new warnings
./build.sh # or Build.cmd on Windows - Test: Run relevant tests to verify functionality
./test.sh # or Test.cmd on Windows - Code style: Verify changes match the repository's coding standards
- Check file headers (.NET Foundation header)
- Verify naming conventions (especially field prefixes)
- Ensure using directives are outside namespace
- Confirm line endings are correct for file type
- Documentation: Update if your changes affect public APIs or behavior
When builds or tests fail, follow this diagnostic process:
- Check build logs: Look at
artifacts/log/Build.binlogusing the Binary Log Viewer - Review terminal output: MSBuild errors will show the failing project and error code
- Check test results: Detailed test logs are in
artifacts/TestResults/ - For native builds: Review CMake output for missing dependencies or configuration issues
- Clean and rebuild: Sometimes required after changing build configuration files:
./build.sh -rebuild
- Create a branch: Create a feature branch from
mainwith a descriptive name - Make changes: Implement your changes following the coding standards
- Build locally: Run
./build.sh(orBuild.cmdon Windows) to ensure the code compiles - Run tests: Execute
./test.sh(orTest.cmdon Windows) to verify functionality - Commit changes: Make small, logical commits with clear commit messages
- Push to remote: Push your branch to the remote repository
- Create pull request: Open a PR with a clear description of your changes
- Address feedback: Respond to review comments and make necessary updates
- Merge: Once approved, the PR will be merged to
main
- Make small, incremental changes rather than large, sweeping modifications
- Test frequently to catch issues early
- Commit logical units of work separately
- Keep the build and tests passing at each commit when possible
- Title: Use a clear, descriptive title that summarizes the change
- Description: Explain what changed, why it changed, and how to test it
- Link issues: Reference related issues using "Fixes #1234" or "Addresses #1234"
- Keep focused: Each PR should address a single concern or feature
- Respond promptly: Address review feedback in a timely manner
The main solution file is build.sln at the root. Important: This file is auto-generated from build.proj.
- Do NOT manually edit
build.sln - Regenerate after adding/removing projects:
- Linux/macOS:
./eng/generate-sln.sh - Windows:
.\eng\generate-sln.ps1
- Linux/macOS:
- The solution is regenerated automatically during builds when needed
NuGet Package Versions:
The repository uses a centralized version management system:
eng/Versions.props: Defines all NuGet package versions for the repo- Always update this file when changing package versions
- Use the
nugetMCP tool to query and resolve version conflicts
eng/Version.Details.props: Auto-generated by Arcade/Darc- Never edit directly - requires modifying Version.Details.xml.
eng/Version.Details.xml: Dependency tracking metadata- Never edit directly - requires metadata not available to agents.
Package Source Configuration:
- Never modify
NuGet.configto add a source feed unless explicitly requested - Never add
nuget.orgas a source toNuGet.config - Use the
nugetMCP tool for querying packages and resolving conflicts
Project References:
- Use relative paths in
.csprojfiles when adding dependencies between projects Example:<ProjectReference Include="..\Microsoft.Diagnostics.DebugServices\Microsoft.Diagnostics.DebugServices.csproj" />
Native Dependencies:
- Handled through machine-wide installation or container installation
- See
documentation/building/for platform-specific prerequisites
The repository supports multiple platforms (Windows, Linux, macOS, FreeBSD, NetBSD):
- Use conditional compilation (
#if,#ifdef) for platform-specific code - Leverage .NET's platform detection APIs
- Keep platform-specific code minimal and isolated
Visual Studio Code:
- Open the repository root folder
- Load
build.slnfor better IntelliSense - Use the provided launch configurations in
.vscode
Visual Studio:
start-vs.cmd- Build failures:
- Ensure all prerequisites are installed (see
documentation/building/) - Check
artifacts/log/Build.binlogfor detailed error information
- Ensure all prerequisites are installed (see
- Test failures:
- Some tests require specific runtime versions or configurations
- Check test output in
artifacts/TestResults/if using global test script - Verify you built before testing (test scripts don't rebuild)
- Native component issues:
- Check terminal output for cl/clang/cmake error output.
- Line ending issues:
- Shell scripts fail on Linux/macOS: Check for CRLF line endings
- Ensure
.editorconfigsettings are being respected by your editor
- NuGet packages: Add to
eng/Versions.propswith appropriate version and never modifyNuGet.configto add a source feed unless asked to do so specifically. Particularly, never addnuget.orgas a source toNuGet.config. Use thenugetMCP as needed to query and solve for assembly version conflicts. - Security: Be mindful of security implications when adding dependencies
- Licensing: Ensure new dependencies are compatible with MIT license
- Minimize dependencies: Only add when necessary
- Never commit secrets or credentials
- Follow secure coding practices (input validation, proper error handling)
- Be cautious with native interop and memory management
- Review security implications of changes
- Write tests for new functionality: New features should include tests
- Don't remove existing tests: Tests verify important functionality
- Fix test failures related to your changes: Don't ignore failing tests
- Maintain test quality: Tests should be clear, focused, and maintainable
- Adding new tools or features
- Changing public APIs
- Modifying build or test procedures
- Adding new dependencies or requirements
- Tool documentation:
/documentation/*-instructions.md - Building instructions:
/documentation/building/ - Design documents:
/documentation/design-docs/ - README:
/README.md
- Main development:
mainbranch - Feature branches: Use descriptive names
- Pull requests: Required for all changes
- First line: Brief summary (50 characters or less)
- Blank line, then detailed description if needed
- Reference issues: "Fixes #1234" or "Addresses #1234"
If you encounter issues or have questions:
- Check existing documentation in
/documentation - Review closed issues and pull requests for similar problems
- Consult the FAQ
- Ask in the issue or pull request you're working on