Home | Projects | Notes > Linux Device Drivers > Error Handling & Error Codes
The Linux kernel coding standard document recommends using the goto
statement of the C programming language for error handling. (Only for error handling)
This is just a recommendation!
Error handling structure using if...else
statement:
xxxxxxxxxx
191if (try_something_1 != Err)
2{
3 if (try_something_2 != Err)
4 {
5 if (try_something_3 != Err)
6 {
7
8 }
9 else
10 {
11 undo_try_something_2;
12 undo_try_something_1;
13 }
14 }
15 else
16 {
17 undo_try_something_1;
18 }
19}
You must UNDO the previous successful operations when an error is encountered along the way because there might be some resources opened or held by those operations.
Error handling structure using goto
statement:
xxxxxxxxxx
131if (try_something_1 == Err)
2 goto err1;
3if (try_something_2 == Err)
4 goto err2;
5if (try_something_3 == Err)
6 goto err3;
7
8err3:
9 undo_try_something_2;
10err2:
11 undo_try_something_1;
12err1:
13 return ret;
Looks cleaner than when using
if...else
statement.
if...else
and goto
statements can also be used in combination.
Some kernel macros can be used to deal with return of error pointers by kernel functions.
The reason why the kernel functions do not simply return NULL
upon fail is because NULL
does not give any idea what went well. Instead, the kernel functions are generally designed to return a pointer that can be interpreted to a meaningful value that tells the user what went wrong.
The following are most frequently used macros (defined in include/linux/err.h
) help understand what caused the kernel function fail.
IS_ERR()
PTR_ERR()
ERR_PTR()
Your device driver (or kernel module) should be designed to return an appropriate error code when an error happens.
The user space global variable errno
will be set to that error code from the kernel space so that the user space code is able to understand what has gone wrong in the kernel space.
Error codes are defined in the file include/uapi/asm-generic/errno-base.h
xxxxxxxxxx
401/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2
3
4
5/* Operation not permitted */
6/* No such file or directory */
7/* No such process */
8/* Interrupted system call */
9/* I/O error */
10/* No such device or address */
11/* Argument list too long */
12/* Exec format error */
13/* Bad file number */
14/* No child processes */
15/* Try again */
16/* Out of memory */
17/* Permission denied */
18/* Bad address */
19/* Block device required */
20/* Device or resource busy */
21/* File exists */
22/* Cross-device link */
23/* No such device */
24/* Not a directory */
25/* Is a directory */
26/* Invalid argument */
27/* File table overflow */
28/* Too many open files */
29/* Not a typewriter */
30/* Text file busy */
31/* File too large */
32/* No space left on device */
33/* Illegal seek */
34/* Read-only file system */
35/* Too many links */
36/* Broken pipe */
37/* Math argument out of domain of func */
38/* Math result not representable */
39
40