3 error, nexterror, poperror, waserror \- error handling functions
14 #define poperror() (up->nerrlab--)
17 #define waserror() (setlabel(&up->errlab[up->nerrlab++]))
19 The kernel handles error conditions using non-local gotos,
22 but using a stack of error labels to implement nested exception handling.
23 This simplifies many of the internal interfaces by eliminating the need
24 for returning and checking error codes at every level of the call stack,
25 at the cost of requiring kernel routines to adhere to a strict discipline.
27 Each process has in its defining kernel
29 structure a stack of labels,
31 (currently 64) elements deep.
32 A kernel function that must perform a clean up or recovery action on an error
33 makes a stylised call to
49 When called in the normal course of events,
51 registers an error handling block by pushing its label onto the stack,
55 should be tested as shown above.
56 If non-zero (true), the calling function should perform the needed
57 error recovery, ended by a call to
59 to transfer control to the next location on the error stack.
60 Typical recovery actions include deallocating memory, unlocking resources, and
61 resetting state variables.
63 Within the recovery block,
64 after handling an error condition, there must normally
67 to transfer control to any error recovery lower down in the stack.
68 The main exception is in the outermost function in a process,
71 (there being nothing further on the stack), but calls
76 to terminate the process.
78 When the need to recover a particular resource has passed,
79 a function that has called
82 remove the corresponding label from the stack by calling
86 be done before returning from the function; otherwise, a subsequent call to
88 will return to an obsolete activation record, with unpredictable but unpleasant consequences.
91 copies the given error message, which is limited to
95 of the current process,
96 enables interrupts by calling
102 to start invoking the recovery procedures currently stacked by
105 .B /sys/src/9/port/error.h
106 offers a wide selection of predefined error messages, suitable for almost any occasion.
107 The message set by the most recent call to
109 can be obtained within the kernel by examining
111 and in an application, by using the
116 A complex function can have nested error handlers.
119 block will follow the acquisition of a resource, releasing it
120 on error before calling
124 will precede its release in the normal case.
133 if(waserror()){ /* A */
137 m = mallocz(READSTR, 0);
139 error(Enomem); /* returns to A */
140 if(waserror()){ /* B */
142 nexterror(); /* invokes A */
145 poperror(); /* pops B */
147 poperror(); /* pops A */
155 error(Egreg); /* returns to B */
160 .B /sys/src/9/port/proc.c
162 The description above has many instances of