В этой статье приводятся ответы на часто задаваемые вопросы о сборе дампов в .NET.
Почему сбор дампов не удаётся в Linux?
Чтобы реализовать коллекцию дампов, .NET обрабатывает дочерний процесс, называемый createdump. Этот дочерний процесс использует API Linux ptrace(), а также считывает из файловой системы /proc для доступа к данным потока и памяти, записанным в файл дампа. Хотя использование API разрешено параметрами безопасности по умолчанию во многих дистрибутивах Linux, иногда менее распространенная конфигурация безопасности отклонит доступ. Вы можете увидеть выходные данные процесса createdump, написанного на консоли дампа приложения, например:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Одна из причин, по которой доступ может быть отклонен, заключается в том, что песочница безопасности перехватывает вызов с помощью фильтра BPF seccomp. Для приложений, работающих в контейнере с использованием технологии Open Container Initiative, профиль seccomp должен разрешать вызовы ptrace. Например, Docker использует containerd в качестве среды исполнения контейнеров на уровне системы. При инициализации он указывает профиль seccomp по умолчанию, позволяющий ptrace только в том случае, если узел контейнера имеет версию ядра выше 4.8 или если CAP_SYS_PTRACE в контейнере была указана возможность.
Если вызовы не перехватываются, ядро выполняет различные встроенные проверки доступа. Документация по ptrace() содержит подробное описание в конце под названием "Проверка режима доступа Ptrace", в котором описывается, как это сделать. Доступ к файловой системе /proc также использует вариант проверки того же режима доступа ptrace. Ниже приведена сокращенная сводка по выполненным проверкам безопасности и местам, где доступ может быть запрещен:
- Либо вызывающий процесс должен иметь тот же идентификатор пользователя, что и целевой процесс, либо вызывающий процесс должен иметь CAP_SYS_PTRACE. Если ни из этих значений нет, доступ запрещен. Так как среда выполнения .NET ничего не делает, чтобы изменить учетную запись пользователя при запуске createdump, идентификаторы пользователей должны соответствовать, и этот шаг должен завершиться успешно.
- Если у createdump нет CAP_SYS_PTRACE (по умолчанию он его не имеет), то целевой процесс должен быть помечен как допускающий дампирование. По умолчанию большинство процессов в Linux можно дампировать, но этот параметр можно изменить, вызвав prctl() с опцией PR_SET_DUMPABLE. Если вы добавите возможности процессу с помощью инструмента setcap, это может также привести к тому, что процесс перестанет быть дампируемым. Более подробное описание параметра dumpable и причин его отключения см. в документации по Linux.
- Перечисляются все включенные модули безопасности Linux (LSM), и каждый из них должен утвердить доступ. К сожалению, если LSM запрещает доступ, в Linux отсутствует единый механизм отчетности, чтобы узнать, какая система безопасности отвечает за это. Вместо этого необходимо определить, какие из них включены в системе, а затем изучить каждый из них по отдельности. Вы можете определить, какие LSM активны, выполнив следующие действия:
cat /sys/kernel/security/lsmХотя любой LSM может быть ответственным, Yama, SELinux и AppArmor часто являются соответствующими.
AppArmor и SELinux имеют широкие механизмы конфигурации и отчетов, поэтому если вам нужно узнать, как работать с ними, лучше всего просмотреть собственную документацию каждого проекта. Yama имеет только один параметр конфигурации, который можно отобразить, выполнив следующие действия:
cat /proc/sys/kernel/yama/ptrace_scope
Эта команда выводит число, указывающее текущую политику безопасности Yama ptrace:
- 0: классические разрешения ptrace.
- 1. Ограниченный ptrace.
- 2. Присоединение только для администраторов.
- 3. Нет подключения.
Yama должен предоставить доступ для createdump в рамках политик 0 и 1, но предполагается, что доступ будет запрещен в рамках политик 2 и 3. Политика 3 всегда запрещает доступ, а политика 2 по умолчанию не работает, потому что createdump обычно не имеет возможности CAP_SYS_PTRACE.
Почему я получаю дампы только в Linux, если dotnet-dump или мой процесс сбоя выполняется с повышенными привилегиями?
Некоторые системы, основанные на Linux, настроены с политиками безопасности, которые требуют, чтобы любой процесс, собирающий дамп, имел возможность с характеристикой CAP_SYS_PTRACE. Как правило, процессы не имеют этой возможности, но запуск с повышенными привилегиями является одним из способов его включения. Полное описание того, как политики безопасности Linux влияют на сбор дампов, см. в статье "Почему сбор дампов завершается сбоем в Linux?".
Почему я не могу собирать дампы при выполнении внутри контейнера?
Для приложений, работающих под любой технологией Open Container Initiative, seccomp профиль должен разрешать вызовы к ptrace(). Например, Docker использует containerd в качестве среды выполнения контейнеров. При инициализации среды выполнения указывается профиль seccomp по умолчанию, который разрешает ptrace только в том случае, если узел контейнера имеет версию ядра выше 4.8 или если была указана соответствующая системная возможность CAP_SYS_PTRACE.
Полное описание того, как политики безопасности Linux влияют на сбор дампов, см. в разделе "Почему сбор дампов завершается сбоем в Linux?".
Почему я не могу собирать дампы на macOS?
В macOS использование ptrace требует, чтобы целевой процесс имел соответствующие разрешения у хоста. Сведения о минимальных обязательных правах см. в разделе " Права по умолчанию".
Почему я не могу собирать дампы на Android или iOS?
Сбор дампов не поддерживается на мобильных платформах (Android и iOS). Эти платформы используют среду выполнения Mono, которая не поддерживает создание дампа памяти.
Где можно узнать больше о том, как использовать дампы для диагностики проблем в приложении .NET?
Ниже приведены некоторые дополнительные ресурсы:
Как решить проблему "Не удалось найти любую совместимую версию платформы"
В Linux DOTNET_ROOT переменная среды должна указывать на правильную папку при установке. Если он указывает на другую версию .NET, dotnet-dump всегда создает эту ошибку.
DOTNET_ROOT Если переменная среды не задана, создается другая ошибка ("Необходимо установить .NET для запуска этого приложения").