wandres.dev
ERRORES DEL KERNEL · ERR_PTR, goto, -errno

Códigos de error y su propagación

El vocabulario de errores del kernel: los -errno más comunes, qué significa cada uno, y la disciplina de propagarlos sin perder información.

⏱ 9 min

Elegir el código de error correcto no es un detalle: es lo que ve el usuario cuando algo falla (como el mensaje “Permission denied” o “No such device”). El kernel tiene un vocabulario preciso de errores, y usarlo bien hace que los fallos sean diagnosticables.

🎯 Al terminar esta lección sabrás
  • Los códigos de error más comunes.
  • Elegir el correcto para cada situación.
  • Propagar sin perder información.
  • De -errno a mensaje de usuario.

El vocabulario de errores

Los códigos viven en include/uapi/asm-generic/errno-base.h y errno.h. Los que más usarás:

Código Significado
-EINVAL argumento inválido
-ENOMEM sin memoria
-ENODEV no existe el dispositivo
-EBUSY recurso ocupado
-EPERM / -EACCES sin permiso / acceso denegado
-EFAULT dirección de memoria inválida (frontera user, nivel 12)
-EAGAIN inténtalo de nuevo (recurso temporalmente no disponible)
-ENOSYS no implementado
-EIO error de entrada/salida

Elegir el correcto

El código de error es una API, no un detalle interno

Un error mal elegido confunde a quien depura; uno bien elegido guía directo al problema. El código que devuelves cruza la frontera al usuario: la libc lo convierte en el errno que ve el programa, y en el mensaje que lee la persona (“Cannot allocate memory”, “Device or resource busy”). Por eso importa ser preciso: -EINVAL si el usuario pasó basura, -ENOMEM si te quedaste sin memoria, -EBUSY si el recurso está en uso, -EPERM si no tiene permiso. Devolver -EINVAL para todo es como escribir “algo falló” en cada error de un programa: técnicamente informa, pero desperdicia la oportunidad de comunicar qué falló. Los códigos de error son parte del contrato de tu driver con el mundo. Trátalos con el mismo cuidado que el resto de la API.

Propagar sin perder información

La disciplina: cuando una función que llamas falla, propaga su código hacia arriba, no lo aplastes con uno genérico:

ret = operacion_que_puede_fallar();
if (ret)
	return ret;          /* propaga el error ORIGINAL, no un -EINVAL genérico */

Así el error específico (p. ej. -ENOMEM de un kmalloc profundo) llega intacto hasta arriba, y el diagnóstico es posible. Aplastarlo a -EINVAL en cada capa destruye la información justo cuando más la necesitas.

💡
perror y errno en el otro lado

Recuerda el círculo completo: tu -ENOMEM en el kernel se convierte, tras la syscall, en errno = ENOMEM en el programa de usuario, que perror() imprime como “Cannot allocate memory”. Cuando elijas un código, imagina ese mensaje final. Es la diferencia entre un usuario que entiende qué pasó y uno perdido ante un “Invalid argument” que no explica nada.

⚔️ Habla el idioma de los errores
  1. Para cada caso, elige el -errno: (a) puntero de usuario inválido, (b) sin memoria, (c) dispositivo en uso, (d) el usuario pasó un tamaño negativo.
  2. Escribe una cadena de funciones donde el error de la más profunda se propague intacto hasta arriba.
  3. Desde userspace, provoca un error de una syscall y mira errno con perror.
  4. Explora errno-base.h en el árbol del kernel.