Share via


Diagnostische poorten

Dit artikel is van toepassing op: ✔️ .NET Core 3.1 en latere versies

De .NET-runtime maakt een service-eindpunt beschikbaar waarmee andere processen diagnostische opdrachten kunnen verzenden en antwoorden kunnen ontvangen via een IPC-kanaal. Dit eindpunt wordt een diagnostische poort genoemd. Opdrachten kunnen worden verzonden naar de diagnostische poort naar:

  • Leg een geheugendump vast.
  • Start een EventPipe-trace .
  • Vraag de opdrachtregel aan die wordt gebruikt om de app te starten.

De diagnostische poort ondersteunt verschillende transporten, afhankelijk van het platform. Momenteel maken zowel de CoreCLR- als Mono-runtime-implementaties gebruik van Named Pipes in Windows en Unix Domain Sockets in Linux en macOS. De Mono-runtime-implementatie op Android, iOS en tvOS maakt gebruik van TCP/IP. Het kanaal maakt gebruik van een aangepast binair protocol. De meeste ontwikkelaars communiceren nooit rechtstreeks met het onderliggende kanaal en protocol, maar gebruiken eerder GUI- of CLI-hulpprogramma's die namens hen communiceren. De hulpprogramma's dotnet-dump en dotnet-trace abstract verzenden van protocolopdrachten om dumps vast te leggen en traceringen te starten. Voor ontwikkelaars die aangepaste hulpprogramma's willen schrijven, biedt het NuGet-pakket Microsoft.Diagnostics.NETCore.Client een .NET API-abstractie van het onderliggende transport en protocol.

Beveiligingsoverwegingen

De diagnostische poort bevat gevoelige informatie over een actieve toepassing. Als een niet-vertrouwde gebruiker toegang krijgt tot dit kanaal, kan deze de gedetailleerde programmastatus observeren, inclusief eventuele geheimen die zich in het geheugen bevinden en de uitvoering van het programma willekeurig wijzigen. In de CoreCLR-runtime is de standaarddiagnosepoort zo geconfigureerd dat deze alleen toegankelijk is voor hetzelfde gebruikersaccount dat de app heeft gestart of door een account met supergebruikersmachtigingen. Als uw beveiligingsmodel andere processen met dezelfde gebruikersaccountreferenties niet vertrouwt, kunt u alle diagnostische poorten uitschakelen door omgevingsvariabele DOTNET_EnableDiagnostics=0in te stellen. Met deze instelling kunt u geen externe hulpprogramma's gebruiken, zoals .NET-foutopsporing of een van de diagnostische hulpprogramma's dotnet-*.

Notitie

.NET 6 standaardiseert het voorvoegsel DOTNET_ in plaats van COMPlus_ voor omgevingsvariabelen die .NET-runtimegedrag configureren. COMPlus_ Het voorvoegsel blijft echter werken. Als u een eerdere versie van de .NET-runtime gebruikt, moet u nog steeds het COMPlus_ voorvoegsel voor omgevingsvariabelen gebruiken.

Standaarddiagnosepoort

In Windows, Linux en macOS heeft de runtime standaard één diagnostische poort geopend op een bekend eindpunt. Dit is de poort waarmee de diagnostische hulpprogramma's van dotnet-* automatisch verbinding maken wanneer ze niet expliciet zijn geconfigureerd voor het gebruik van een alternatieve poort. Het eindpunt is:

  • Windows - Named Pipe \\.\pipe\dotnet-diagnostic-{pid}
  • Linux en macOS - Unix Domain Socket {temp}/dotnet-diagnostic-{pid}-{disambiguation_key}-socket

{pid} is de proces-id die in decimaal is geschreven, {temp} de TMPDIR omgevingsvariabele of de waarde /tmp als TMPDIR deze niet gedefinieerd/leeg is en {disambiguation_key} de begintijd van het proces is geschreven in decimaal. Op macOS en NetBSD is de begintijd van het proces het aantal seconden sinds UNIX-tijdsperiode. Op alle andere platforms is het sinds de opstarttijd jiffs.

De runtime tijdens het opstarten onderbreken

De runtime voert standaard beheerde code uit zodra deze wordt gestart, ongeacht of er diagnostische hulpprogramma's zijn verbonden met de diagnostische poort. Soms is het handig om de runtime te laten wachten met het uitvoeren van beheerde code totdat een diagnostisch hulpprogramma is verbonden, om het initiële programmagedrag te observeren. Het instellen van de omgevingsvariabele DOTNET_DefaultDiagnosticPortSuspend=1 zorgt ervoor dat de runtime wacht totdat een hulpprogramma verbinding maakt met de standaardpoort. Als er na enkele seconden geen hulpprogramma is gekoppeld, drukt de runtime een waarschuwingsbericht af aan de console waarin wordt uitgelegd dat er nog steeds wordt gewacht tot een hulpprogramma is gekoppeld.

Aanvullende diagnostische poorten configureren

Notitie

Dit werkt alleen voor apps met .NET 5 of hoger.

Zowel de Mono- als CoreCLR-runtimes kunnen aangepaste geconfigureerde diagnostische poorten in de connect rol gebruiken. Mono ondersteunt ook aangepaste TCP/IP-poorten in de listen rol, wanneer deze worden gebruikt met dotnet-dsrouter op Android of iOS. Deze aangepaste poorten zijn naast de standaardpoort die beschikbaar blijft. Er zijn enkele veelvoorkomende redenen waarom aangepaste poorten nuttig zijn:

  • In Android, iOS en tvOS is er geen standaardpoort, dus het configureren van een poort is nodig voor het gebruik van diagnostische hulpprogramma's.
  • In omgevingen met containers of firewalls kunt u een voorspelbaar eindpuntadres instellen dat niet varieert op basis van proces-id, zoals de standaardpoort. Vervolgens kan de aangepaste poort expliciet worden toegevoegd aan een acceptatielijst of worden geproxied over een bepaalde beveiligingsgrens.
  • Voor bewakingshulpprogramma's is het handig om het hulpprogramma te laten luisteren op een eindpunt en de runtime probeert er actief verbinding mee te maken. Dit voorkomt dat u het bewakingsprogramma nodig hebt om continu te peilen naar nieuwe apps die worden gestart. In omgevingen waarin de standaarddiagnosepoort niet toegankelijk is, hoeft u de monitor ook niet te configureren met een aangepast eindpunt voor elke bewaakte app.

In elk communicatiekanaal tussen een diagnostisch hulpprogramma en de .NET-runtime moet de ene kant de listener zijn en wachten tot de andere kant verbinding maakt. De runtime kan worden geconfigureerd om te handelen in de connect rol voor elke poort. (De Mono-runtime kan ook worden geconfigureerd om te handelen in de listen rol voor elke poort.) Poorten kunnen ook onafhankelijk worden geconfigureerd om te onderbreken bij het opstarten, wachtend tot een diagnostisch hulpprogramma een cv-opdracht uit te geven. Poorten die zijn geconfigureerd om verbinding te maken, herhalen hun verbindingspogingen voor onbepaalde tijd als het externe eindpunt niet luistert of als de verbinding is verbroken. De app onderbreekt echter niet automatisch beheerde code terwijl deze verbinding tot stand wordt gebracht. Als u wilt dat de app wacht tot er een verbinding tot stand is gebracht, gebruikt u de optie onderbreken bij het opstarten.

Aangepaste poorten worden geconfigureerd met behulp van de DOTNET_DiagnosticPorts omgevingsvariabele. Deze variabele moet worden ingesteld op een door puntkomma's gescheiden lijst met poortbeschrijvingen. Elke poortbeschrijving bestaat uit een eindpuntadres en optionele modifiers die de runtime connect of listen rol beheren en als de runtime moet worden onderbroken bij het opstarten. In Windows is het eindpuntadres de naam van een benoemde pipe zonder het \\.\pipe\ voorvoegsel. In Linux en macOS is dit het volledige pad naar een Unix-domeinsocket. In Android, iOS en tvOS is het adres een IP en poort. Voorbeeld:

  1. DOTNET_DiagnosticPorts=my_diag_port1 - (Windows) De runtime maakt verbinding met de benoemde pipe \\.\pipe\my_diag_port1.
  2. DOTNET_DiagnosticPorts=/foo/tool1.socket;foo/tool2.socket - (Linux en macOS) De runtime maakt verbinding met zowel de Unix Domain Sockets /foo/tool1.socket als /foo/tool2.socket.
  3. DOTNET_DiagnosticPorts=127.0.0.1:9000 - (Android, iOS en tvOS) De runtime maakt verbinding met IP 127.0.0.1 op poort 9000.
  4. DOTNET_DiagnosticPorts=/foo/tool1.socket,nosuspend - (Linux en macOS) Dit voorbeeld heeft de nosuspend wijzigingsfunctie. De runtime probeert verbinding te maken met Unix Domain Socket /foo/tool1.socket die door een extern hulpprogramma wordt gemaakt. Aanvullende diagnostische poorten veroorzaken normaal gesproken dat de runtime wordt onderbroken bij het opstarten totdat een cv-opdracht wordt uitgevoerd, maar nosuspend zorgt ervoor dat de runtime niet wacht.

De volledige syntaxis voor een poort is address[,(listen|connect)][,(suspend|nosuspend)]. connect is de standaardinstelling als geen van beide connect is listen opgegeven (en listen alleen wordt ondersteund door de Mono-runtime op Android of iOS). suspend is de standaardwaarde als geen van suspend beide of nosuspend is opgegeven.

Gebruik in diagnostische hulpprogramma's voor dotnet

Hulpprogramma's zoals dotnet-dump, dotnet-counters en dotnet-trace alle ondersteuning collect of monitor werkwoorden die via de diagnostische poort communiceren met een .NET-app.

  • Wanneer deze hulpprogramma's het --processId argument gebruiken, berekent het hulpprogramma automatisch het standaardadres van de diagnostische poort en maakt er verbinding mee.
  • Wanneer u het --diagnostic-port argument opgeeft, luistert het hulpprogramma naar het opgegeven adres en moet u de DOTNET_DiagnosticPorts omgevingsvariabele gebruiken om uw app te configureren om verbinding te maken. Zie De diagnostische poort gebruiken voor een volledig voorbeeld met dotnet-tellers.

DS-router gebruiken om de diagnostische poort te proxyn

Alle diagnostische hulpprogramma's van dotnet-* verwachten verbinding te maken met een diagnostische poort die een lokale Named Pipe of Unix Domain Socket is. Mono wordt vaak uitgevoerd op geïsoleerde hardware of in emulators die een proxy via TCP nodig hebben om toegankelijk te worden. Het hulpprogramma dotnet-dsrouter kan een lokale Named Pipe of Unix Domain Socket proxyn naar TCP, zodat de hulpprogramma's in deze omgevingen kunnen worden gebruikt. Zie dotnet-dsrouter voor meer informatie.