orange's学习--第八章:实现IPC--实现assert ()和panic()

宏定义:

#define assert(exp)  if (exp) ; \
        else assertion_failure(
#exp, __FILE__, __BASE_FILE__, __LINE__)    这个#exp不知道什么意义

注意其中的__FILE__、__BASE_FILE__和__LINE__这三个宏,它们的意义如下: 这是编译器默认展开的变量。

         __FILE__将被展开成当前输入的文件。在这里,它告诉我们哪个文件中产生了异常。 
         __BASE_FILE__可被认为是传递给编译器的那个文件名。比如你在m.c中包含了n.h,而n.h中的某一个assert函数失败了,则__FILE__为n.h,__BASE_FILE__为m.c。 
         __LINE__将被展开成当前的行号。

/*****************************************************************************
 *                           assertion_failure
 *************************************************************************//**
 * Invoked by assert().
 * @param exp       The failure expression itself.
 * @param file      __FILE__
 * @param base_file __BASE_FILE__
 * @param line      __LINE__
 *****************************************************************************/
PUBLIC void assertion_failure(char *exp, char *file, char *base_file, int line)
{
    printl("%c  assert(%s) failed: file: %s, base_file: %s, ln%d",
           MAG_CH_ASSERT, exp, file, base_file, line);

    /**
     * If assertion fails in a TASK, the system will halt before
     * printl() returns. If it happens in a USER PROC, printl() will
     * return like a common routine and arrive here. 
     * @see sys_printx()
     * 
     * We use a forever loop to prevent the proc from going on:
     */
    spin("assertion_failure()");

    /* should never arrive here */
        __asm__ __volatile__("ud2");
}

/*****************************************************************************
 *                                spin
 *****************************************************************************/
PUBLIC void spin(char * func_name)
{
    printl("\nspinning in %s ...\n", func_name);
    while (1) {}

使用了一个改进后的打印函数,叫做printl(),它其实就是一个定义成printf的宏,不过这里的printf跟上一章中的稍有不同,它将调用一个叫做printx的系统调用,并最终调用函数sys_printx ()。

     * @note Code in both Ring 0 and Ring 1~3 may invoke printx().
     * If this happens in Ring 0, no linear-physical address mapping  is needed.

    /**
     * @note if assertion fails in any TASK, the system will be halted;
     * if it fails in a USER PROC, it'll return like any normal syscall does.
     */

sys_printx ()将首先判断首字符是否为预先设定的 “Magic  Char”,如果是的话,则做响应的特殊处理。我们的assertion_failure(  )就使用了MAG_CH_ASSERT作为 “Magic Char”。当sys_printx ()发现传入字符串的第一个字符是MAG_CH_ASSERT时,会同时判断调用系统调用的进程是系统进程 (TASK)还是用户进程 (USER  PROC),如果是系统进程,则停止整个系统的运转,并将要打印的字符串打印在显存的各处;如果是用户进程,则打印之后像一个普通的printx调用一样返回,届时该用户进程会因为assertion_failure(  )中对函数spin (  )的调用而进入死循环。换言之,系统进程的assert失败会导致系统停转, 用户进程的失败仅仅使自己停转。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值