Assert () and panic ()

Source: Internet
Author: User

Assert () and panic ()
Let's first look at assert (). You may have been using this function for a long time, but previously you used a ready-made assert, which can be easily used as long as it contains a header file. Now everything has to be self-reliant, but don't worry, it is not difficult to write an Assert function. See the following code:
12 # define assert
13 # ifdef assert
14 void assertion_failure (char * exp, char * file, char * base_file, int line );
15 # define assert (exp) if (exp );/
16 else assertion_failure (# exp, _ file __, _ base_file __, _ line __)
17 # else
18 # define assert (exp)
19 # endif
Note the following three macros: _ file _, _ base_file _, and _ line _. Their meanings are as follows: [1].
_ File __: the input file is expanded. Here, it tells us which file has an exception.
_ Base_file __: the file name that can be considered to be passed to the compiler. For example, in M. C contains N. h, while n. if an Assert function in H fails, _ file _ is N. h ,__ base_file _ is M. c.
_ Line __: it is expanded into the current row number.
After understanding the meanings of these macros, the remaining assertion_failure () function is easy. Its function is to print out the location where the error occurs:
42 Public void assertion_failure (char * exp, char * file, char * base_file, int line)
43 {
44 printl ("% C) lost assert (% s) failed: lost file: Lost % s, encrypted base_file: Lost % s, lost ln % d ",
45 mag_ch_assert,
46 exp, file, base_file, line );
47
48 /**
49 * If assertion fails in a task, the system will halt before
50 * printl () returns. If it happens in a user proc, printl () will
51 * return like a common routine and arrive here.
52 * @ see sys_printx ()
53 *
54 * we use a forever loop to prevent the proc from going on:
55 */
56 spin ("assertion_failure ()");
57
58/* shocould never arrive here */
59 _ ASM _ volatile _ ("ud2 ");
60}
Note that a little trick is used here, that is, an improved printing function called printl (), which is actually a macro defined as printf, however, the printf here is slightly different from the previous chapter. It will call a system call called printx and finally call the function sys_printx (), which is located in TTY. c:
181 public int sys_printx (INT _ unused1, int _ unused2, char * s, struct proc * p_proc)
182 {
183 const char * P;
184 char ch;
185
186 char reenter_err [] = "? When k_reenter partition is invalid incorrect partition for unknown reason ";
187 reenter_err [0] = mag_ch_panic;
188
189 /**
190 * @ note code in both ring 0 and ring 1 ~ 3 may invoke printx ().
191 * If this happens in Ring 0, no linear-physical address mapping
192 * is needed.
193 *
194 * @ attention the value of 'K _ reenter' is tricky here. When
195 *-# printx () is called in Ring 0
196 *-k_reenter> 0. When code in Ring 0 callprintx (),
197 * an 'interrupt re-enter' will occur (printx () generates
198 * a software interrupt). Thus 'K _ reenter' will be increased
199 * by 'kernel. ASM: save' and be greater than 0.
200 *-# printx () is called in ring 1 ~ 3
201 *-k_reenter = 0.
202 */
203 If (k_reenter = 0)/* printx () called in ring <1 ~ 3> */
204 P = va2la (proc2pid (p_proc), S );
205 else if (k_reenter> 0)/* printx () called in ring <0> */
206 P = s;
207 else/* This shocould not happen */
208 p = reenter_err;
209
210 /**
211 * @ note if assertion fails in any task, the system will be halted;
212 * if it fails in a user proc, it'll return like any normal syscall
213 * does.
214 */
215 if (* P = mag_ch_panic) |
216 (* P = mag_ch_assert & p_proc_ready <& proc_table [nr_tasks]) {
217 disable_int ();
218 char * V = (char *) v_mem_base;
219 const char * q = p + 1;/* + 1: Skip the magic char */
220
221 while (v <(char *) (v_mem_base + v_mem_size )){
222 * V ++ = * q ++;
223 * V ++ = red_char;
224 if (! * Q ){
225 while (INT) V-v_mem_base) % (scr_width * 16 )){
226/** v ++ = '';*/
227 v ++;
228 * V ++ = gray_char;
229}
230 q = p + 1;
231}
232}
233
234 _ ASM _ volatile _ ("hlt ");
235}
236
237 while (CH = * P ++ )! = 0 ){
238 If (CH = mag_ch_panic | CH = mag_ch_assert)
239 continue;/* skip the magic char */
240
241 out_char (tty_table [p_proc-> nr_tty]. p_console, CH );
242}
243
244 return 0;
245}
It is easy to see that sys_printx () will first determine whether the first character is a preset "Magic char". If yes, it will perform special response processing. Our assertion_failure () uses mag_ch_assert as "Magic char ". When sys_printx () finds that the first character of the input string is mag_ch_assert, it also determines whether the process called by the system is a system process (task) or a user process (User proc ), if it is a system process, the entire system is stopped, and the strings to be printed are printed everywhere. If it is a user process, the printed strings are returned like a normal printx call, at that time, the user process will enter an endless loop because of the call to the function spin () in assertion_failure. In other words, the Assert failure of the system process will cause the system to stop, and the failure of the user process will only stop itself.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.