다음을 통해 공유


진단 포트

이 문서의 적용 대상: ✔️ .NET Core 3.1 이상 버전

.NET 런타임은 다른 프로세스가 진단 명령을 보내고 IPC 채널을 통해 응답을 받을 수 있도록 하는 서비스 엔드포인트를 노출합니다. 이 엔드포인트를 진단 포트라고 합니다. 다음을 위해 진단 포트로 명령을 보낼 수 있습니다.

  • 메모리 덤프를 캡처합니다.
  • EventPipe 추적을 시작합니다.
  • 앱을 시작하는 데 사용되는 명령줄을 요청합니다.

진단 포트는 플랫폼에 따라 다양한 전송을 지원합니다. 현재 CoreCLR 및 Mono 런타임 구현은 모두 Windows의 명명된 파이프와 Linux 및 macOS의 Unix 도메인 소켓을 사용합니다. Android, iOS 및 tvOS의 Mono 런타임 구현은 TCP/IP를 사용합니다. 채널은 사용자 지정 이진 파일 프로토콜을 사용합니다. 대부분의 개발자는 기본 채널 및 프로토콜과 직접 상호 작용하지 않으며 오히려 대신 통신하는 GUI 또는 CLI 도구를 사용합니다. 예를 들어, dotnet-dumpdotnet-trace 도구는 전송 프로토콜 명령을 추상화하여 덤프를 캡처하고 추적을 시작합니다. 사용자 지정 도구를 작성하려는 개발자를 위해 Microsoft.Diagnostics.NETCore.Client NuGet 패키지는 기본 전송 및 프로토콜의 .NET API 추상화를 제공합니다.

보안 고려 사항

진단 포트는 실행 중인 애플리케이션에 대한 중요한 정보를 노출합니다. 신뢰할 수 없는 사용자가 이 채널에 액세스하면 메모리에 있는 모든 비밀을 포함하여 자세한 프로그램 상태를 관찰하고 프로그램 실행을 임의로 수정할 수 있습니다. CoreCLR 런타임에서 기본 진단 포트는 앱을 시작한 동일한 사용자 계정이나 슈퍼 사용자 권한이 있는 계정에서만 액세스할 수 있도록 구성됩니다. 보안 모델이 동일한 사용자 계정 자격 증명을 가진 다른 프로세스를 신뢰하지 않는 경우 환경 변수 DOTNET_EnableDiagnostics=0을 설정하여 모든 진단 포트를 사용하지 않도록 설정할 수 있습니다. 이 설정은 .NET 디버깅이나 dotnet-* 진단 도구와 같은 외부 도구를 사용하는 기능을 차단합니다.

참고 항목

.NET 6은 .NET 런타임 동작을 구성하는 환경 변수에 대해 COMPlus_ 대신 접두사 DOTNET_을 표준화합니다. 그러나 COMPlus_ 접두사도 계속 작동합니다. 이전 버전의 .NET 런타임을 사용하는 경우에도 환경 변수에 COMPlus_ 접두사를 사용해야 합니다.

기본 진단 포트

Windows, Linux 및 macOS의 경우 런타임에는 잘 알려진 엔드포인트에 기본적으로 하나의 진단 포트가 열려 있습니다. 이는 dotnet-* 진단 도구가 대체 포트를 사용하도록 명시적으로 구성되지 않은 경우 자동으로 연결하는 포트입니다. 엔드포인트:

  • Windows - 명명된 파이프 \\.\pipe\dotnet-diagnostic-{pid}
  • Linux 및 macOS - Unix 도메인 소켓 {temp}/dotnet-diagnostic-{pid}-{disambiguation_key}-socket

{pid}는 10진수로 작성된 프로세스 ID이고, {temp}TMPDIR 환경 변수 또는 값 /tmp(TMPDIR이 정의되지 않거나 비어 있는 경우)이며, {disambiguation_key}는 10진수로 작성된 프로세스 시작 시간입니다. macOS 및 NetBSD에서 프로세스 시작 시간은 UNIX epoch 시간 이후의 시간(초)입니다. 다른 모든 플랫폼에서는 부팅 후 매우 빠르게 수행됩니다.

시작 시 런타임 일시 중단

기본적으로 런타임은 진단 도구가 진단 포트에 연결되었는지 여부에 관계없이 시작하자마자 관리 코드를 실행합니다. 초기 프로그램 동작을 관찰하기 위해 진단 도구가 연결될 때까지 런타임이 관리 코드 실행을 기다리도록 하는 것이 유용한 경우가 있습니다. 환경 변수 DOTNET_DefaultDiagnosticPortSuspend=1을 설정하면 도구가 기본 포트에 연결될 때까지 런타임이 대기하게 됩니다. 몇 초 후에도 도구가 연결되지 않으면 런타임은 도구가 연결되기를 기다리고 있음을 설명하는 경고 메시지를 콘솔에 표시합니다.

추가 진단 포트 구성

참고 항목

본 작업은 .NET 5 이상을 실행하는 앱에만 적용됩니다.

Mono 및 CoreCLR 런타임 모두 connect 역할에서 사용자 지정 구성된 진단 포트를 사용할 수 있습니다. Mono는 Android 또는 iOS에서 dotnet-dsrouter와 함께 사용될 때 listen 역할에서 사용자 지정 TCP/IP 포트도 지원합니다. 이러한 사용자 지정 포트는 계속 사용 가능한 기본 포트에 추가됩니다. 사용자 지정 포트가 유용한 몇 가지 일반적인 이유는 다음과 같습니다.

  • Android, iOS, tvOS에는 기본 포트가 없으므로 진단 도구를 사용하려면 포트를 구성해야 합니다.
  • 컨테이너나 방화벽이 있는 환경에서는 기본 포트처럼 프로세스 ID에 따라 달라지지 않는 예측 가능한 엔드포인트 주소를 설정하려고 할 수 있습니다. 그런 다음 사용자 지정 포트를 허용 목록에 명시적으로 추가하거나 일부 보안 경계를 넘어 프록시할 수 있습니다.
  • 모니터링 도구는 엔드포인트에서 수신 대기하도록 하여 런타임이 적극적으로 이 도구에 연결을 시도할 수 있도록 하는 데 유용합니다. 이렇게 하면 새 앱 시작을 지속적으로 폴링하기 위해 모니터링 도구가 필요하지 않습니다. 기본 진단 포트에 액세스할 수 없는 환경에서는 모니터링되는 각 앱에 대한 사용자 지정 엔드포인트로 모니터를 구성할 필요도 없습니다.

진단 도구와 .NET 런타임 간의 각 통신 채널에서 한쪽은 수신기가 되어야 하며 다른 쪽이 연결될 때까지 기다려야 합니다. 모든 포트에 대해 connect 역할을 수행하도록 런타임을 구성할 수 있습니다. (모든 포트에 대해 listen 역할을 수행하도록 Mono 런타임을 구성할 수도 있습니다.) 또한 시작 시 일시 중지되고 진단 도구가 다시 시작 명령을 실행할 때까지 기다리도록 포트를 독립적으로 구성할 수도 있습니다. 연결하도록 구성된 포트는 원격 엔드포인트가 수신 대기하지 않거나 연결이 끊어진 경우 연결 시도를 무기한 반복합니다. 그러나 앱은 해당 연결 설정을 기다리는 동안 관리 코드를 자동으로 일시 중단하지 않습니다. 앱이 연결이 설정될 때까지 기다리도록 하려면 시작 시 일시 중지 옵션을 사용합니다.

사용자 지정 포트는 DOTNET_DiagnosticPorts 환경 변수를 사용하여 구성됩니다. 이 변수는 세미콜론으로 구분된 포트 설명 목록으로 설정되어야 합니다. 각 포트 설명은 엔드포인트 주소와 런타임의 connect 또는 listen 역할을 제어하고 런타임이 시작 시 일시 중지되어야 하는지 여부를 제어하는 선택적 한정자로 구성됩니다. Windows에서 엔드포인트 주소는 \\.\pipe\ 접두사가 없는 명명된 파이프의 이름입니다. Linux 및 macOS에서는 Unix 도메인 소켓의 전체 경로입니다. Android, iOS, tvOS에서는 주소가 IP와 포트입니다. 예시:

  1. DOTNET_DiagnosticPorts=my_diag_port1 -(Windows) 런타임이 명명된 파이프 \\.\pipe\my_diag_port1에 연결됩니다.
  2. DOTNET_DiagnosticPorts=/foo/tool1.socket;foo/tool2.socket -(Linux 및 macOS) 런타임이 Unix 도메인 소켓 /foo/tool1.socket/foo/tool2.socket에 모두 연결됩니다.
  3. DOTNET_DiagnosticPorts=127.0.0.1:9000 -(Android, iOS 및 tvOS) 런타임이 포트 9000에서 IP 127.0.0.1에 연결됩니다.
  4. DOTNET_DiagnosticPorts=/foo/tool1.socket,nosuspend -(Linux 및 macOS) 이 예에는 nosuspend 한정자가 있습니다. 런타임은 외부 도구가 만드는 Unix 도메인 소켓 /foo/tool1.socket에 연결을 시도합니다. 추가 진단 포트를 사용하면 일반적으로 시작 시 다시 시작 명령을 기다리면서 런타임이 일시 중단되지만, nosuspend는 런타임이 기다리지 않도록 합니다.

포트의 전체 구문은 address[,(listen|connect)][,(suspend|nosuspend)]입니다. connect 또는 listen이 모두 지정되지 않은 경우 connect가 기본값입니다(그리고 listen은 Android 또는 iOS의 Mono 런타임에서만 지원됩니다). suspend 또는 nosuspend가 모두 지정되지 않은 경우 suspend가 기본값입니다.

dotnet 진단 도구에서의 사용법

dotnet-dump, dotnet-countersdotnet-trace와 같은 도구는 모두 진단 포트를 통해 .NET 앱과 통신하는 collect 또는 monitor 동사를 지원합니다.

  • 이러한 도구가 --processId 인수를 사용하는 경우 도구는 기본 진단 포트 주소를 자동으로 계산하여 연결합니다.
  • --diagnostic-port 인수를 지정할 때 도구는 지정된 주소에서 수신 대기하며 DOTNET_DiagnosticPorts 환경 변수를 사용하여 연결하도록 앱을 구성해야 합니다. dotnet-counters의 전체 예를 보려면 진단 포트 사용을 참조하세요.

ds-router를 사용하여 진단 포트 프록시

모든 dotnet-* 진단 도구는 로컬 명명된 파이프 또는 Unix 도메인 소켓인 진단 포트에 연결될 것으로 예상합니다. Mono는 종종 격리된 하드웨어나 액세스하기 위해 TCP를 통한 프록시가 필요한 에뮬레이터에서 실행됩니다. dotnet-dsrouter 도구는 해당 환경에서 도구를 사용할 수 있도록 로컬 명명된 파이프 또는 Unix 도메인 소켓을 TCP로 프록시할 수 있습니다. 자세한 내용은 dotnet-dsrouter를 참조하세요.