En este artículo se responde a las preguntas más frecuentes sobre la recopilación de volcados de memoria en .NET.
¿Por qué falla la recopilación de volcados en Linux?
Para implementar la recopilación de volcados, los procesos de .NET generan un proceso secundario denominado createdump. Este proceso secundario utiliza la API de Linux ptrace() y también lee desde el sistema de archivos /proc para acceder a los datos de subprocesos y memoria que se escriben en el archivo de volcado. Aunque la configuración de seguridad predeterminada permite el uso de la API en muchas distribuciones de Linux, a veces una configuración de seguridad menos común denegará el acceso. Es posible que veas la salida del proceso createdump escrita en la consola de la aplicación de la que se está realizando el volcado, como por ejemplo:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Una razón por la que se puede denegar el acceso es si un espacio aislado de seguridad intercepta la llamada mediante un filtro BPF seccomp. En el caso de las aplicaciones que se ejecutan en un contenedor mediante la tecnología Open Container Initiative, el seccomp perfil debe permitir llamadas a ptrace. Por ejemplo, Docker utiliza containerd como entorno de ejecución de contenedores en segundo plano. Al inicializar, especifica un perfil de seccomp predeterminado que solo permite ptrace si el host del contenedor tiene una versión de kernel superior a la 4.8 o si se especificó la CAP_SYS_PTRACE funcionalidad en el contenedor.
Si las llamadas no se interceptan, el kernel realiza una variedad de comprobaciones de acceso integradas. Los documentos de ptrace() incluyen una descripción detallada cerca del final, titulada "Comprobación del modo de acceso de Ptrace", que describe cómo se realizan. El acceso al sistema de archivos /proc también emplea una variante del mismo método de verificación del modo de acceso de ptrace. Lo siguiente es un resumen abreviado de las comprobaciones de seguridad realizadas y lugares donde se puede denegar el acceso:
- El proceso de llamada debe tener el mismo identificador de usuario que el proceso de destino o el proceso de llamada debe tener CAP_SYS_PTRACE. Si ninguno de estos valores es verdadero, se deniega el acceso. Dado que el entorno de ejecución de .NET no hace nada para cambiar la cuenta de usuario al iniciar createdump, los identificadores de usuario deben coincidir y este paso debe realizarse correctamente.
- Si createdump no tiene CAP_SYS_PTRACE (por defecto, no lo tiene), entonces el proceso de destino que se va a volcar debe estar marcado como "dumpable". De forma predeterminada, la mayoría de los procesos en Linux son volcables, pero puedes cambiar esta configuración llamando a prctl() con la opción PR_SET_DUMPABLE. Si añades capacidades a un proceso utilizando la herramienta setcap, esto también puede hacer que un proceso deje de ser volcable. Para obtener una descripción más detallada de la configuración de volcado y de qué provoca que se desactive, consulte la documentación de Linux.
- Todos los módulos de seguridad de Linux habilitados (LSM) se enumeran y cada uno de ellos debe aprobar el acceso. Desafortunadamente, si un LSM deniega el acceso, no hay ningún mecanismo uniforme de informes de Linux para saber cuál es el responsable. En su lugar, debe determinar cuáles están habilitados en el sistema y, a continuación, investigar cada uno individualmente. Puede determinar qué LSM están activos mediante la ejecución de:
cat /sys/kernel/security/lsm. Aunque cualquier LSM podría ser responsable, Yama, SELinux y AppArmor suelen ser los relevantes.
AppArmor y SELinux tienen mecanismos completos de configuración e informes, por lo que si necesita aprender a trabajar con ellos, es mejor ver la documentación propia de cada proyecto. Yama solo tiene una configuración única, que se puede mostrar ejecutando:
cat /proc/sys/kernel/yama/ptrace_scope
Este comando genera un número que indica la directiva de seguridad de Yama ptrace actual:
- 0: Permisos clásicos de ptrace.
- 1: ptrace restringido.
- 2: Acoplamiento solo para administradores.
- 3: Sin adjuntar.
Yama debería conceder acceso a createdump bajo las políticas 0 y 1, pero se espera que se niegue el acceso bajo las políticas 2 y 3. La directiva 3 siempre deniega el acceso y la directiva 2 no funciona de forma predeterminada porque createdump normalmente no tiene la funcionalidad CAP_SYS_PTRACE.
¿Por qué solo obtengo volcados en Linux si dotnet-dump o el proceso que se bloquea se ejecutan con privilegios elevados?
Algunos sistemas basados en Linux están configurados con directivas de seguridad que exigen que cualquier proceso que recopile un volcado tenga la capacidad CAP_SYS_PTRACE. Normalmente, los procesos no tienen esta funcionalidad, pero la ejecución con privilegios elevados es una manera de habilitarla. Para obtener una descripción más detallada de cómo las directivas de seguridad de Linux afectan a la recopilación de volcados, consulta ¿Por qué falla la recopilación de volcados en Linux?.
¿Por qué no puedo recopilar volcados de memoria al ejecutarse dentro de un contenedor?
En el caso de las aplicaciones que se ejecutan en cualquier tecnología Open Container Initiative, el seccomp perfil debe permitir llamadas a ptrace(). Por ejemplo, Docker utiliza containerd como entorno de ejecución de contenedores en segundo plano. Al inicializar el entorno de ejecución, especifica un perfil de seccomp predeterminado que solo permite ptrace si el host del contenedor tiene una versión de kernel superior a la 4.8 o si se especificó la CAP_SYS_PTRACE funcionalidad.
Para obtener una descripción más detallada de cómo las directivas de seguridad de Linux afectan a la recopilación de volcados, consulta la pregunta ¿Por qué falla la recopilación de volcados en Linux?.
¿Por qué no puedo recopilar volcados en macOS?
En macOS, el uso de ptrace requiere que el host del proceso de destino esté adecuadamente autorizado. Para obtener información sobre los derechos mínimos necesarios, consulte Derechos predeterminados.
¿Por qué no puedo recopilar volcados en Android o iOS?
La recopilación de volcados no es compatible con plataformas móviles (Android e iOS). Estas plataformas usan el entorno de ejecución Mono, que no admite la generación de volcados de memoria.
¿Dónde puedo obtener más información sobre cómo puedo aprovechar los volcados de memoria para ayudar a diagnosticar problemas en mi aplicación .NET?
Estos son algunos recursos adicionales:
Cómo puedo resolver "No era posible encontrar ninguna versión de marco compatible"
En Linux, la DOTNET_ROOT variable de entorno debe apuntar a la carpeta correcta cuando se establece. Cuando apunta a otra versión de .NET, dotnet-dump siempre genera este error. Cuando no se establece la DOTNET_ROOT variable de entorno, se produce un error diferente ("Debe instalar .NET para ejecutar esta aplicación").