zoukankan      html  css  js  c++  java
  • Solaris学习笔记(4)

    Solaris学习笔记(4)

    作者: Badcoffee
    Email:
    blog.oliver@gmail.com
    Blog: http://blog.csdn.net/yayong
    2007年2月

    很久没有写blog了,工作越来越忙,生活中琐事也不少,一天中的时间所剩无几了。当初很想写出精品的技术文章来,到后来才发现,要写一篇精品真的很难。从基础理论到实际案例,想深入潜出又要有一定水准,真的是太难了,这中间得花费写作者的多少心智?现在才能体会到成为一名出色的技术作家,需要的不仅仅是技术功底而已。所以,还是先做好工程师这份没有前途的职业再说吧:)

    关键词:RISC/CISC/SPARC/ABI/MDB/KMDB/Solaris/OpenSolaris

    本文介绍Solaris SPARC系统上Crashdump分析所需的基础知识:寄存器窗口,ABI等;Solaris的内核调试工具已经可以很好地读取出函数的入口参数,但是,在一些情况下,仍旧需要通过读取线程栈的内容来确定函数参数的值。再次说明,本文仅用于学习交流目的,错误再所难免,如果有勘误或疑问请与作者联系。

    RISC 与 CISC

    关于RISC与CISC的争论由来以久,相关文章到处都是,不明白可以Google一下。似乎两者已经互相借鉴,互相融合了,如果有时间,应该深入了解一下CPU和体系结构方面的知识。

    SPARC体系结构的文档,可以从下面的网站得到,本文只涉及到crash dump分析的基础。

    http://www.sparc.org/

    SPARC的特点

    1. 精简指令集;

    2. 指令和操作基于寄存器,内存访问需要专门的load/store操作;

    3. 有很多寄存器(几百个),通过寄存器窗口来访问;

    4. 函数参数传递也通过寄存器,而不是通过栈;

    5. 指令编码定长;

    6. 地址对齐,不对齐的地址会引发bad trap;例如,各种数据类型必须与其自然边界对齐;

    7. 字节序缺省是大端的(也可支持小端,需要页表项的特殊设置);

    SPARC寄存器

    Processor Status Register (PSR):用来指示kernel/user mode, condition codes, CPU priority level等。

    Program Counter (PC): 当前正在执行的指令地址;

    next Program Counter (nPC):下条要执行指令的地址;

    General-purpose registers:通用寄存器,实际上SPARC有数百个寄存器,但对每个程序仅可见32个,这是通过寄存器窗口实现的。

    寄存器窗口中的通用寄存器分类

    General-purpose registers %r0 … %r31

    1. 全局寄存器(8个) - 对所有程序可见

    General-purpose global registers %g0 … %g7 Same as %r0 … %r7

    2. 输出寄存器(8个) -函数返回值,输出寄存器是下一个窗口的输入寄存器

    General-purpose out registers %o0 … %o7 Same as %r8 … %r15

    3. 局部寄存器(8个) - 仅本函数可见

    General-purpose local registers %l0 … %l7 Same as %r16 … %r23

    4. 输入寄存器(8个) -本函数的输入参数,来自于上一窗口的输出寄存器

    General-purpose in registers %i0 … %i7 Same as %r24 … %r31

    寄存器窗口

    SPARCv9寄存器窗口的数量范围从 2 到 32,具体取决于处理器实现。每个寄存器窗口对应一个函数,当每个函数被调用时,函数开始会调用save指令分配相应的栈空间;

    函数的调用必然引起一次窗口的切换和一次栈空间的预先分配,但寄存器在下列情况时才被保存在栈上,

        1. 寄存器窗口用尽时

        2. 上下文切换

        3. flushw指令

    这时会引发一个硬件的溢出trap,将寄存器窗口中的16个寄存器(8个局部寄存器和8个输入寄存器)保存到栈上;

    寄存器窗口还有underflow trap,可以把保存在栈里的值恢复;restore指令用于切回上级调用的寄存器窗口,并取释放栈空间;

    相关的指令

    1. 函数调用:

    call address

    或者

    jmpl address, %o7

    2. 函数入场:

    save %sp, -0x78, %sp

    3. 函数返回:

    jmpl %i7+8, %g0
    restore

    或者

    ret
    restore

    SPARC的ABI

    函数的调用者传递参数到本窗口的o寄存器,被掉函数从本窗口的i寄存器读到;

    %o0到%o5 - 用于函数返回值或者传递给下一个函数参数,第一个参数是%o0 ,参数多于6个还会用栈传递;

    %o6 - %sp栈顶指针;

    %o7 -函数返回地址;

    %i6 -%fp栈框架指针(SFP)

    %i0到%i5 -入口参数,第一个参数是%i0,来自于上一窗口的输出参数;

    %g0永远是0,特殊用途;

    SPARC V9的 stack bias:

    %o6 is still referred to as the stack pointer register %sp, and %i6 is the frame pointer register %fp. However, the %sp and %fp registers are offset by a constant, known as the stack bias, from the actual memory location of the stack. The size of the stack bias is 2047 bytes.

    栈框架的定义

    Solaris中,stack frame的格式定义在体系结构相关的头文件中:

    http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sparc/sys/frame.h#36

     /*

     * Definition of the sparc stack frame (when it is pushed on the stack).

     
    */

    struct frame {

    long fr_local[8]; /* saved locals */

    long fr_arg[6]; /* saved arguments [0 - 5] */

    struct frame *fr_savfp; /* saved frame pointer */

    long fr_savpc; /* saved program counter */

    #if !defined(__sparcv9)

    char *fr_stret; /* struct return addr */

    #endif /* __sparcv9 */

    long fr_argd[6]; /* arg dump area */

    long fr_argx[1]; /* array of args past the sixth */

    };


    实际验证

    在console上激活kmdb,用$<systemdump产生一个crashdump。可以根据上面的

    头文件验证栈内寄存器窗口值的保存是与上面定义一致的。之所以产生一个crash dump来验证,

    是为防止寄存器窗口还没有保存在栈里。

    # mdb 0
    > ::stackregs
    000002a100347111 abort_seq_softintr
    +0x94(1814400, 18cc800, 300077d4000, 3f70, 11870400)
      
    %l0-%l3:          1821d40    22d3188da0893                0                0
      
    %l4-%l7:                0          18cc800          191bc00          1010184
      intr_thread
    +0x2c0:       jmpl      %o5, %o7

    000002a1003472d1 intr_thread
    +0x2c0(0, 1859ff8, 180c000, 1b, 10b5fd8, 1817c00)
      
    %l0-%l3:          1008468                a       4414001602              80a
      
    %l4-%l7:                0                0                0      2a10030f980
    mdb: failed to read instruction at 
    0: no mapping for address

    000002a10030f221 
    0(1817c00, 0, 300077d4000, ffffffffffffffff, 21816800)
      
    %l0-%l3:      60000128fe8               1b                0 ffffffffffffffff
      
    %l4-%l7:      60000128fe8 ffffffffffffffff          1859ff8          106b174
      thread_start
    +4:          jmpl      %i7, %o7

    000002a10030f2d1 thread_start
    +4(000000)
      
    %l0-%l3:                0                0                0                0
      
    %l4-%l7:                0                0                0                0

    > ::regs
    %g0 = 0x0000000000000000                 %l0 = 0x000006000013c200 
    %g1 = 0x0000000000000000                 %l1 = 0x0000000000000001 
    %g2 = 0x0000000000000000                 %l2 = 0x0000000000000001 
    %g3 = 0x0000000001853400 cpunodes+0x1140 %l3 = 0x00000600002b4a10 
    %g4 = 0x0000000000000000                 %l4 = 0x000000000191c040 
    pci_intr_dma_sync
    %g5 = 0x000000000109a800                 %l5 = 0x0000000000000001 
    %g6 = 0x0000000000000010                 %l6 = 0x0000000000000002 
    %g7 = 0x000002a100347cc0                 %l7 = 0x0000000000000001 

    %o0 = 0x0000000000000000                 %i0 = 0x0000000000000000 
    %o1 = 0x0000000000020040                 %i1 = 0x000000000000000a 
    %o2 = 0x0000000001851000 lgrp_stats+0x12f8 %i2 = 0x000000000000000a 
    %o3 = 0x0000000000000001                 %i3 = 0x0000000001814400 
    %o4 = 0x00000000013446a4 kmdbmod`kaif_enter %i4 = 0x0000000000000000 
    %o5 = 0x00000000018ea2b8 kmdbmod`kaif_dvec %i5 = 0x0000000001853400 
    cpunodes
    +0x1140
    %o6 = 0x000002a100347041                 %i6 = 0x000002a100347111 
    %o7 = 0x000000000101028c debug_enter+0x108 %i7 = 0x000000000100ff38 
    abort_seq_softintr
    +0x94

     
    %ccr = 0x00 xcc=nzvc icc=nzvc
    %fprs = 0x00 fef=0 du=0 dl=0
     
    %asi = 0x00                          
       
    %= 0x0000000000000000
      
    %pc = 0x0000000000000000 
     
    %npc = 0x0000000000000004 
      
    %sp = 0x000002a100347041 unbiased=0x000002a100347840
      
    %fp = 0x000002a100347111

      
    %tick = 0x000006b00af1f9fe
       
    %tba = 0x0000000000000000
        
    %tt = 0x9
        
    %tl = 0x0
       
    %pil = 0xc
    %pstate = 0x016 cle=0 tle=0 mm=TSO red=0 pef=1 am=0 priv=1 ie=1 ag=0

           
    %cwp = 0x05  %cansave = 0x00
    %canrestore = 0x00 %otherwin = 0x00
        
    %wstate = 0x00 %cleanwin = 0x00
    > 0x000002a100347111+0t2047,24/naJ
    0x2a100347910:  
    0x2a100347910:  1821d40         
    0x2a100347918:  22d3188da0893   
    0x2a100347920:  0               
    0x2a100347928:  0               
    0x2a100347930:  0               
    0x2a100347938:  18cc800         
    0x2a100347940:  191bc00         
    0x2a100347948:  1010184         
    0x2a100347950:  1814400         
    0x2a100347958:  18cc800         
    0x2a100347960:  300077d4000     
    0x2a100347968:  3f70            
    0x2a100347970:  1               
    0x2a100347978:  1870400         
    0x2a100347980:  2a1003472d1     
    0x2a100347988:  100c714         
    0x2a100347990:  3000793e0b8     
    0x2a100347998:  0               
    0x2a1003479a0:  0               
    0x2a1003479a8:  0               
    0x2a1003479b0:  3000793e028     
    0x2a1003479b8:  3000793e030     
    0x2a1003479c0:  1fafdd                
    0x2a1003479c8:  3000793e030     
    0x2a1003479d0:  0               
    0x2a1003479d8:  6000003b6e0     
    0x2a1003479e0:  300347221       
    0x2a1003479e8:  1fafdd          
    0x2a1003479f0:  1297538         
    0x2a1003479f8:  413             
    0x2a100347a00:  1297518         
    0x2a100347a08:  6000003b6e0     
    0x2a100347a10:  13c200          
    0x2a100347a18:  0               
    0x2a100347a20:  0               
    0x2a100347a28:  600002b4a10     
    > 2a1003472d1+0t2047,24/naJ
    0x2a100347ad0:  
    0x2a100347ad0:  1008468         
    0x2a100347ad8:  a               
    0x2a100347ae0:  4414001602      
    0x2a100347ae8:  80a             
    0x2a100347af0:  0               
    0x2a100347af8:  0               
    0x2a100347b00:  0               
    0x2a100347b08:  2a10030f980     
    0x2a100347b10:  0               
    0x2a100347b18:  1859ff8         
    0x2a100347b20:  180c000         
    0x2a100347b28:  1b              
    0x2a100347b30:  10b5fd8         
    0x2a100347b38:  1817c00         
    0x2a100347b40:  2a10030f221     
    0x2a100347b48:  0               
    0x2a100347b50:  baddcafebaddcafe 
    0x2a100347b58:  baddcafebaddcafe 
    0x2a100347b60:  baddcafebaddcafe 
    0x2a100347b68:  baddcafebaddcafe 
    0x2a100347b70:  baddcafebaddcafe 
    0x2a100347b78:  baddcafebaddcafe 
    0x2a100347b80:  baddcafebaddcafe      
    0x2a100347b88:  baddcafebaddcafe 
    0x2a100347b90:  baddcafebaddcafe 
    0x2a100347b98:  baddcafebaddcafe 
    0x2a100347ba0:  baddcafebaddcafe 
    0x2a100347ba8:  baddcafebaddcafe 
    0x2a100347bb0:  baddcafebaddcafe 
    0x2a100347bb8:  baddcafebaddcafe 
    0x2a100347bc0:  baddcafebaddcafe 
    0x2a100347bc8:  baddcafebaddcafe 
    0x2a100347bd0:  baddcafebaddcafe 
    0x2a100347bd8:  baddcafebaddcafe 
    0x2a100347be0:  baddcafebaddcafe 
    0x2a100347be8:  baddcafebaddcafe 

    相关文档:

    Solaris学习笔记(3)
    Solaris学习笔记(2)
    Solaris学习笔记(1)
    X86汇编语言学习手记(3)

    X86汇编语言学习手记(2)
    X86汇编语言学习手记(1)


    Technorati Tag: OpenSolaris
    Technorati Tag: Solaris

  • 相关阅读:
    javascript教程系列-10.DOM(下)
    javascript教程系列-9.DOM(上)
    javascript教程系列-8.BOM
    javascript教程系列-7.Date对象
    javascript教程系列-6.String类型
    javascript教程系列-5.数组
    Python字符串、元组、列表、字典互相转换的方法
    python 中函数
    python中的字符串 列表 字典
    python 基础 知识
  • 原文地址:https://www.cnblogs.com/ainima/p/6330809.html
Copyright © 2011-2022 走看看