• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術博客

            感興趣領域:高性能服務器編程,存儲,算法,Linux內核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數據加載中……

            linux內核V2.6.11學習筆記(5)--異常處理

            這里以除0錯誤這個異常來講解異常處理的機制.

            1) 注冊異常處理函數
            在系統初始化的時候,調用trap_init函數注冊異常處理函數.
            這個函數里調用set_trap_gate(0,&divide_error);注冊除0錯誤的異常由divide_error函數處理,而這個錯誤的中斷向量號是0.

            2) 當異常被觸發時,調用原先注冊的divide_error函數.
            這個函數的實現的Entry.S文件中:
            ENTRY(divide_error)
                pushl $
            0            # no error code
                pushl $do_divide_error
                ALIGN
            error_code:
                pushl 
            %ds
                pushl 
            %eax
                xorl 
            %eax, %eax
                pushl 
            %ebp
                pushl 
            %edi
                pushl 
            %esi
                pushl 
            %edx
                decl 
            %eax            # eax = -1
                pushl 
            %ecx
                pushl 
            %ebx
                cld
                movl 
            %es, %ecx
                movl ES(
            %esp), %edi        # get the function address
                movl ORIG_EAX(
            %esp), %edx    # get the error code
                movl 
            %eax, ORIG_EAX(%esp)
                movl 
            %ecx, ES(%esp)
                movl $(__USER_DS), 
            %ecx
                movl 
            %ecx, %ds
                movl 
            %ecx, %es
                movl 
            %esp,%eax            # pt_regs pointer
                call 
            *%edi
                jmp ret_from_exception
            首先,它將真正的處理函數do_divide_error壓入棧中,其實,對于每個異常而言,真正的處理函數都是名為"do_注冊函數"的函數.
            緊跟著,將一些需要保存的寄存器也壓入棧中.
            接著,由于處理函數的地址已經在edi寄存器中了,調用call *%edi調用處理函數.
            當處理完畢之后,調用函數ret_from_exception從異常處理中返回.

            上面是大致的流程,下面詳細看看do_divide_error函數做了什么.
            這個函數的實現在文件trap.c中:
            #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
            fastcall 
            void do_##name(struct pt_regs * regs, long error_code) \
            { \
                siginfo_t info; \
                info.si_signo 
            = signr; \
                info.si_errno 
            = 0; \
                info.si_code 
            = sicode; \
                info.si_addr 
            = (void __user *)siaddr; \
                
            if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
                                    
            == NOTIFY_STOP) \
                    
            return; \
                do_trap(trapnr, signr, str, 
            1, regs, error_code, &info); \
            }

            DO_VM86_ERROR_INFO( 
            0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
            可以看到,最終這個函數會走到do_trap函數中,接著看這個函數中的代碼片段:
                trap_signal: {
                    
            struct task_struct *tsk = current;
                    tsk
            ->thread.error_code = error_code;
                    tsk
            ->thread.trap_no = trapnr;
                    
            if (info)
                        force_sig_info(signr, info, tsk);
                    
            else
                        force_sig(signr, tsk);
                    
            return;
                }
            首先得到當前進程的指針,在進程結構體的thread結構體中保存error_code和trapnr,也就是錯誤號和中斷向量.
            接著調用force_sig_info函數,可以跟進這個函數,其實最終要做的就是將該異常以信號量的形式加入到當前進程的信號集合中,也就是給當前進程發送信號,告訴進程有異常被觸發了,需要處理.以除0錯誤來看,這個信號量是SIGFPE.



            posted on 2009-04-29 21:45 那誰 閱讀(3244) 評論(0)  編輯 收藏 引用 所屬分類: linux kernel

            国产精品久久久久久久| 久久精品国产亚洲AV忘忧草18| 久久久久99精品成人片直播| 77777亚洲午夜久久多人| 久久久久99精品成人片试看| 99久久夜色精品国产网站| 精品久久综合1区2区3区激情| 思思久久好好热精品国产| 国产精品无码久久久久久| 久久九九免费高清视频| 无码人妻精品一区二区三区久久 | 久久久受www免费人成| 久久久久久久综合狠狠综合| 99国产精品久久久久久久成人热| 久久一本综合| 婷婷综合久久狠狠色99h| 2021国内久久精品| 精品国产婷婷久久久| 久久久久久久久久久久中文字幕 | 久久夜色精品国产噜噜亚洲AV| 久久99国产精品99久久| 亚洲AV无码久久精品蜜桃| 色综合久久天天综线观看| 国产精品免费久久| 99精品国产在热久久无毒不卡| 久久婷婷午色综合夜啪| 久久久久一级精品亚洲国产成人综合AV区| 亚洲AV无码1区2区久久| 久久经典免费视频| 久久综合偷偷噜噜噜色| 久久中文字幕无码专区| 国产呻吟久久久久久久92| 色综合合久久天天综合绕视看| 久久精品国产亚洲AV无码娇色| 伊人久久综合无码成人网| 中文字幕乱码人妻无码久久| 无码国内精品久久综合88| 国产亚洲美女精品久久久2020| 久久国产精品无| 日韩AV无码久久一区二区 | 国产精品美女久久久免费|