Partilhar via


FAQ para lixeiras

Este artigo responde a perguntas frequentes sobre a coleta de dumps no .NET.

Por que a coleta de dump está falhando no Linux?

Para implementar a coleta de dump, os processos .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 dump. Embora o uso da API seja permitido pelas configurações de segurança padrão em muitas distros Linux, às vezes uma configuração de segurança menos comum negará o acesso. Você pode ver a saída do processo createdump escrita 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)

Uma razão pela qual o acesso pode ser negado é se uma área restrita de segurança intercetar a chamada usando um filtro BPF seccomp. Para aplicativos executados em um contêiner usando a tecnologia Open Container Initiative, o seccomp perfil deve permitir chamadas para ptrace. Por exemplo, Docker usa containerd sob o capô como um tempo de execução de contêiner. Ao inicializar, ele especifica um perfil seccomp padrão que permite ptrace somente se o host do contêiner tiver uma versão do kernel superior a 4.8 ou se a CAP_SYS_PTRACE capacidade foi especificada no contêiner.

Se as chamadas não forem intercetadas, o kernel fará uma variedade de verificações de acesso incorporadas. Os documentos para ptrace() incluem uma descrição detalhada perto do final, intitulada "Ptrace access mode checking", que descreve como eles são feitos. O acesso ao sistema de arquivos /proc também usa uma variação da mesma verificação do modo de acesso ptrace. Segue-se um resumo abreviado dos controlos de segurança realizados e dos locais onde o acesso pode ser recusado:

  • O processo de chamada precisa ter o mesmo ID de usuário que o processo de destino ou o processo de chamada precisa ter CAP_SYS_PTRACE. Se nenhuma destas opções for verdadeira, o acesso será negado. Como o tempo de execução do .NET não faz nada para alterar a conta de usuário ao iniciar createdump, os IDs de usuário devem corresponder e esta etapa deve ser bem-sucedida.
  • Se createdump não tiver CAP_SYS_PTRACE (não por padrão), o processo de destino que está sendo despejado precisa 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 dumpable e o que faz com que ela seja desativada, consulte a documentação do Linux.
  • Todos os módulos de segurança Linux (LSMs) habilitados são enumerados e cada um deles deve aprovar o acesso. Infelizmente, se um LSM negar o acesso, não há um mecanismo uniforme de relatório Linux para saber qual é o 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.

O AppArmor e o SELinux têm mecanismos avançados de configuração e relatórios, portanto, se você precisar aprender a trabalhar com eles, é melhor visualizar a documentação de cada projeto. Yama tem apenas uma única definição de configuração, que pode ser exibida executando:

cat /proc/sys/kernel/yama/ptrace_scope

Este comando gera um número que indica a política de segurança atual do Yama ptrace:

  • 0: Permissões ptrace clássicas.
  • 1: Rastreamento restrito.
  • 2: Anexar somente administrador.
  • 3: Sem anexo.

Yama deve conceder acesso para 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 acesso e a política 2 não funciona por padrão porque createdump normalmente não tem a capacidade CAP_SYS_PTRACE.

Por que eu só recebo dumps no Linux se dotnet-dump ou meu processo de travamento está sendo executado elevado?

Alguns sistemas baseados em Linux são configurados com políticas de segurança que exigem que qualquer processo de coleta de um dump tenha a capacidade CAP_SYS_PTRACE. Normalmente, os processos não têm esse recurso, mas executar elevado é 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 dump, consulte 'Por que a coleta de dump está falhando no Linux?'.

Por que não consigo coletar lixeiras quando estou dentro de um contêiner?

Para aplicativos executados sob qualquer tecnologia Open Container Initiative, o seccomp perfil deve permitir chamadas para ptrace(). Por exemplo, Docker usa containerd sob o capô como um tempo de execução de contêiner. Ao inicializar o tempo de execução, ele especifica um perfil seccomp padrão que permite ptrace somente se o host do contêiner tiver uma versão do kernel superior a 4.8 ou se o CAP_SYS_PTRACE recurso foi especificado.

Para obter uma descrição mais completa de como as políticas de segurança do Linux afetam a coleta de dump, consulte a pergunta 'Por que a coleta de dump está falhando no Linux?'.

Por que não consigo coletar dumps no macOS?

No macOS, o uso de requer que o host do processo de ptrace destino esteja devidamente habilitado. Para obter informações sobre os direitos mínimos exigidos, consulte Direitos padrão.

Onde posso saber mais sobre como posso aproveitar dumps para ajudar a diagnosticar problemas em meu aplicativo .NET?

Aqui estão alguns recursos adicionais:

Como posso resolver "Não foi possível encontrar nenhuma versão compatível do framework"

No Linux, a DOTNET_ROOT variável de 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 variável de ambiente não está definida, um erro diferente é produzido ("Você deve instalar o DOTNET_ROOT .NET para executar este aplicativo").