Este artigo responde a perguntas frequentes sobre a coleta de despejos no .NET.
Por que a coleta de despejo está falhando no Linux?
Para implementar a coleta de despejo, os processos do .NET geram um processo filho chamado createdump. Esse processo filho usa a API do Linux ptrace() e também lê do sistema de arquivos /proc para acessar dados de thread e memória gravados no arquivo de despejo. Embora o uso da API seja permitido pelas configurações de segurança padrão em muitas distribuições do Linux, às vezes, uma configuração de segurança menos comum negará o acesso. Você pode ver a saída do processo de createdump escrito no console do aplicativo que está sendo despejado, como:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Um motivo pelo qual o acesso pode ser negado é se uma área restrita de segurança intercepta a chamada usando um filtro BPF seccomp. Para aplicativos em execução em um contêiner usando a tecnologia Open Container Initiative, o seccomp perfil deve permitir chamadas para ptrace. Por exemplo, Docker usa contêineres sob o capô como um runtime de contêiner. Ao inicializar, ele especifica um perfil seccomp padrão que só permite ptrace se o host de contêiner tiver uma versão de kernel maior que 4.8 ou se a CAP_SYS_PTRACE funcionalidade tiver sido especificada no contêiner.
Se as chamadas não forem interceptadas, o kernel fará uma variedade de verificações de acesso internas. Os documentos para ptrace() incluem uma descrição detalhada perto do final, intitulada "Verificação do modo de acesso do Ptrace", que descreve como elas são feitas. Acessar o sistema de arquivos /proc também usa uma variação da mesma verificação de modo de acesso ptrace. O que se segue é um resumo abreviado das verificações de segurança executadas e locais onde o acesso pode ser negado:
- O processo de chamada precisa ter a mesma ID de usuário que o processo de destino ou o processo de chamada precisa ter CAP_SYS_PTRACE. Se nenhum deles for verdadeiro, o acesso será negado. Como o runtime do .NET não faz nada para alterar a conta de usuário ao iniciar o createdump, as IDs de usuário devem corresponder e essa etapa deve ser bem-sucedida.
- Se o disco criado não tiver CAP_SYS_PTRACE (não tem por padrão), o processo de destino que está sendo despejado precisará ser marcado como "dumpable". Por padrão, a maioria dos processos no Linux são dumpable, mas você pode alterar essa configuração chamando prctl() com a opção PR_SET_DUMPABLE. Se você adicionar recursos a um processo usando a ferramenta setcap, isso também poderá fazer com que um processo pare de ser dumpable. Para obter uma descrição mais detalhada da configuração de dumpable e o que faz com que ela seja desabilitada, consulte a documentação do Linux.
- Todos os LSMs ( módulos de segurança) do Linux habilitados são enumerados e cada um deles deve aprovar o acesso. Infelizmente, se um LSM nega o acesso, não há nenhum mecanismo de relatório linux uniforme para saber qual deles é responsável. Em vez disso, você precisa determinar quais estão habilitados em seu sistema e, em seguida, investigar cada um individualmente. Você pode determinar quais LSMs estão ativos executando:
cat /sys/kernel/security/lsm. Embora qualquer LSM possa ser responsável, Yama, SELinux e AppArmor são frequentemente os relevantes.
AppArmor e SELinux têm mecanismos avançados de configuração e relatório, portanto, se você precisar aprender a trabalhar com eles, é melhor exibir a documentação de cada projeto. O Yama tem apenas uma única configuração, que pode ser exibida executando:
cat /proc/sys/kernel/yama/ptrace_scope
Esse comando gera um número que indica a política de segurança do Yama ptrace atual:
- 0: Permissões de ptrace clássicas.
- 1: ptrace restrito.
- 2: Anexação somente de administrador.
- 3: Sem anexação.
A Yama deve conceder acesso ao createdump nas políticas 0 e 1, mas espera que o acesso seja negado nas políticas 2 e 3. A política 3 sempre nega o acesso e a política 2 não funciona por padrão porque o createdump normalmente não tem a funcionalidade CAP_SYS_PTRACE.
Por que eu só recebo despejos no Linux se o despejo de dotnet ou meu processo de falha estiver sendo elevado?
Alguns sistemas baseados em Linux são configurados com políticas de segurança que exigem que qualquer processo que coleta um despejo tenha a funcionalidade CAP_SYS_PTRACE. Normalmente, os processos não têm essa funcionalidade, mas executar com privilégios elevados é uma maneira de habilitá-lo. Para obter uma descrição mais completa de como as políticas de segurança do Linux afetam a coleta de despejo, consulte 'Por que a coleta de despejo está falhando no Linux?'.
Por que não consigo coletar despejos ao executar dentro de um contêiner?
Para aplicativos em execução em qualquer tecnologia da Open Container Initiative, o seccomp perfil deve permitir chamadas para ptrace(). Por exemplo, Docker usa contêineres sob o capô como um runtime de contêiner. Ao inicializar o runtime, ele especifica um perfil seccomp padrão que só permite ptrace se o host do contêiner tiver uma versão do kernel maior que 4.8 ou se a CAP_SYS_PTRACE funcionalidade tiver sido especificada.
Para obter uma descrição mais completa de como as políticas de segurança do Linux afetam a coleta de despejo, consulte a pergunta "Por que a coleta de despejo está falhando no Linux?".
Por que não consigo coletar despejos no macOS?
No macOS, o uso requer ptrace que o host do processo de destino tenha direito adequado. Para obter informações sobre os direitos mínimos necessários, consulte Direitos padrão.
Onde posso saber mais sobre como aproveitar despejos para ajudar a diagnosticar problemas no meu aplicativo .NET?
Aqui estão alguns recursos adicionais:
Como posso resolver "Não foi possível localizar nenhuma versão de estrutura compatível"
No Linux, a variável de DOTNET_ROOT ambiente deve apontar para a pasta correta quando definida. Quando ele aponta para outra versão do .NET, dotnet-dump sempre produz esse erro. Quando a DOTNET_ROOT variável de ambiente não é definida, um erro diferente é produzido ("Você deve instalar o .NET para executar este aplicativo").