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 por detrás como um runtime 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 "verificação dos modos de acesso do Ptrace", que explica como este processo é realizado. O acesso ao sistema de ficheiros /proc também utiliza uma variação do mesmo método de verificação de modo de acesso por 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: ptrace restrito.
  • Anexo exclusivo para 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 é que só recebo dumps no Linux se o dotnet-dump ou o meu processo que está a falhar estiver a ser executado com privilégios elevados?

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 com privilégios elevados é uma forma de ativar essa funcionalidade. 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 por baixo como um ambiente de execução de contentores. 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, a utilização de ptrace exige que o host do processo de destino esteja devidamente autorizado. Para obter informações sobre os direitos mínimos exigidos, consulte Direitos padrão.

Porque é que não consigo recolher dumps no Android ou iOS?

A recolha de dumps não é suportada em plataformas móveis (Android e iOS). Estas plataformas usam o tempo de execução Mono, que não suporta geração de despejo de memória.

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

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").