Диагностические порты

Эта статья относится к : ✔️ .NET Core 3.1 и более поздним версиям

Среда выполнения .NET предоставляет конечную точку службы, которая позволяет другим процессам отправлять диагностические команды и получать ответы через канал IPC. Эта конечная точка называется портом диагностики. Команды можно отправлять в порт диагностики:

Порт диагностики поддерживает различные транспорты в зависимости от платформы. В настоящее время реализация CoreCLR и Mono используют именованные каналы в сокетах домена Windows и Unix в Linux и macOS. Реализация среды выполнения Mono в Android, iOS и tvOS использует TCP/IP. Канал использует пользовательский двоичный протокол. Большинство разработчиков никогда не будут напрямую взаимодействовать с базовым каналом и протоколом, но вместо этого будут использовать средства GUI или CLI, которые взаимодействуют от их имени. Например, средства dotnet-dump и dotnet-trace абстрактно отправляют команды протокола для записи дампов и запуска трассировок . Для разработчиков, которые хотят писать пользовательские средства, пакет NuGet Microsoft.Diagnostics.NETCore.Client предоставляет абстракцию API .NET для базового транспорта и протокола.

Вопросы безопасности

Порт диагностики предоставляет конфиденциальную информацию о работающем приложении. Если ненадежный пользователь получает доступ к этому каналу, он может наблюдать за подробным состоянием программы, включая все секреты, которые находятся в памяти, и произвольно изменять выполнение программы. В среде выполнения CoreCLR порт диагностики по умолчанию настроен только для той же учетной записи пользователя, которая запустила приложение или учетную запись с разрешениями суперпользователя. Если модель безопасности не доверяет другим процессам с теми же учетными данными учетной записи пользователя, можно отключить все диагностические порты, задав переменную DOTNET_EnableDiagnostics=0среды. Этот параметр блокирует возможность использования внешних инструментов, таких как отладка .NET или любой из средств диагностики dotnet-* .

Примечание.

.NET 6 стандартизует префикс DOTNET_ вместо COMPlus_ для переменных среды, которые настраивают поведение .NET во время выполнения. Но префикс COMPlus_ будет и дальше работать. Если вы используете предыдущую версию среды выполнения .NET, следует и дальше использовать префикс COMPlus_ для переменных среды.

Порт диагностики по умолчанию

В Windows, Linux и macOS среда выполнения имеет один порт диагностики, открытый по умолчанию в известной конечной точке. Это порт, к которому подключаются средства диагностики dotnet-* автоматически, если они не были явно настроены на использование альтернативного порта. Конечная точка:

  • Windows — именованный канал \\.\pipe\dotnet-diagnostic-{pid}
  • Linux и macOS — сокет домена Unix {temp}/dotnet-diagnostic-{pid}-{disambiguation_key}-socket

{pid} — это идентификатор процесса, записанный в десятичном формате, {temp} является TMPDIR переменной среды или значением /tmp , если TMPDIR не определено или пусто, а {disambiguation_key} время начала процесса записывается в десятичном формате. В macOS и NetBSD время начала процесса — это количество секунд с момента эпохи UNIX. На всех других платформах это рифмы с момента загрузки.

Приостановка среды выполнения при запуске

По умолчанию среда выполнения выполняет управляемый код сразу после запуска независимо от того, подключены ли какие-либо средства диагностики к порту диагностики. Иногда полезно ожидать выполнения управляемого кода до тех пор, пока средство диагностики не подключено, чтобы наблюдать за начальным поведением программы. Установка переменной DOTNET_DefaultDiagnosticPortSuspend=1 среды приводит к тому, что среда выполнения будет ждать, пока средство не подключается к порту по умолчанию. Если средство не подключено через несколько секунд, среда выполнения выводит предупреждение в консоль, объясняя, что она по-прежнему ожидает подключения инструмента.

Настройка дополнительных диагностических портов

Примечание.

Это работает только для приложений, использующих .NET 5 или более поздней версии.

Среды выполнения Mono и CoreCLR могут использовать настраиваемые диагностические порты в connect роли. Mono также поддерживает пользовательские порты TCP/IP в listen роли при использовании с dotnet-dsrouter в Android или iOS. Эти пользовательские порты находятся в дополнение к порту по умолчанию, который остается доступным. Существует несколько распространенных причин, по которым полезны пользовательские порты:

  • В Android, iOS и tvOS нет порта по умолчанию, поэтому настройка порта необходима для использования средств диагностики.
  • В средах с контейнерами или брандмауэрами может потребоваться настроить прогнозируемый адрес конечной точки, который не зависит от идентификатора процесса по умолчанию. Затем настраиваемый порт можно явно добавить в список разрешений или прокси-сервер через некоторые границы безопасности.
  • Для средств мониторинга полезно иметь средство прослушивания конечной точки, а среда выполнения активно пытается подключиться к ней. Это позволяет избежать необходимости в средстве мониторинга для непрерывного опроса новых приложений. В средах, где порт диагностики по умолчанию недоступен, он также не требует настройки монитора с пользовательской конечной точкой для каждого отслеживаемого приложения.

В каждом канале обмена данными между средством диагностики и средой выполнения .NET одна сторона должна быть прослушивателем и ожидать подключения другой стороны. Среда выполнения может быть настроена для действия в connect роли любого порта. (Среда выполнения Mono также может быть настроена для действий в listen роли для любого порта.) Порты также можно самостоятельно настроить для приостановки при запуске, ожидая выполнения команды возобновления диагностики. Порты, настроенные для подключения, повторяют попытки подключения на неопределенный срок, если удаленная конечная точка не прослушивается или если подключение потеряно. Но приложение не приостанавливает управляемый код автоматически, ожидая установления этого подключения. Если вы хотите, чтобы приложение ждало установки подключения, используйте параметр приостановки при запуске.

Пользовательские порты настраиваются с помощью переменной DOTNET_DiagnosticPorts среды. Эта переменная должна быть задана в списке описаний портов с запятой. Каждое описание порта состоит из адреса конечной точки и необязательных модификаторов, которые управляют средой выполнения или listen ролью, и если среда выполнения connect должна приостановиться при запуске. В 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) Среда выполнения подключается как к сокетам /foo/tool1.socket домена Unix, так и /foo/tool2.socketк .
  3. DOTNET_DiagnosticPorts=127.0.0.1:9000 — (Android, iOS и tvOS) Среда выполнения подключается к IP-адресу 127.0.0.1 через порт 9000.
  4. DOTNET_DiagnosticPorts=/foo/tool1.socket,nosuspend — (Linux и macOS) Этот пример имеет nosuspend модификатор. Среда выполнения пытается подключиться к сокету /foo/tool1.socket домена Unix, который создает внешнее средство. Дополнительные диагностические порты обычно вызывают приостановку среды выполнения при запуске, ожидая команды возобновления, но nosuspend приводит к тому, что среда выполнения не ожидает.

Полный синтаксис порта.address[,(listen|connect)][,(suspend|nosuspend)] connectзначение по умолчанию, если ни одно или listen не connect указано (и listen поддерживается только средой выполнения Mono в Android или iOS). suspendзначение по умолчанию, если ни указано, nosuspend ни suspend задано.

Использование в средствах диагностики dotnet

Такие средства, как dotnet-dump, dotnet-counters и dotnet-trace все поддержку collect или monitor команды, которые взаимодействуют с приложением .NET через порт диагностики.

  • Когда эти средства используют --processId аргумент, средство автоматически вычисляет адрес порта диагностики по умолчанию и подключается к нему.
  • При указании аргумента --diagnostic-port средство прослушивает заданный адрес и следует использовать DOTNET_DiagnosticPorts переменную среды для настройки приложения для подключения. Полный пример с счетчиками dotnet см. в разделе "Использование порта диагностики".

Использование маршрутизатора ds-маршрутизатора для прокси-сервера диагностики

Все средства диагностики dotnet-* ожидают подключения к порту диагностики, который является локальным именованным каналом или сокетом домена Unix. Mono часто выполняется на изолированном оборудовании или в эмуляторах, которым требуется прокси-сервер через TCP для обеспечения доступности. Средство dotnet-dsrouter может прокси-сервер локального именованного канала или сокета домена Unix к TCP, чтобы средства можно было использовать в этих средах. Дополнительные сведения см. в dotnet-dsrouter.