GCC 生成的符号表调试信息剖析

GCC把C语言源文件('.c')编译成汇编语言文件('.s'),汇编器把汇编语言文件翻译成目标文件('.o'),最后由链接器链接所有的目标文件和有关的库生成可执行文件('a.out')。
如打开'-g'选项,GCC编译'.c'文件时,把附加的调试信息插进'.s'文件,这些调试信息经汇编器和链接器稍加转换一直传到可执行文件中。这些调试信息包括行号、变量的类型和作用域、函数名字、函数参数和函数的作用域等源文件的特性。
在 某些目标文件中,调试信息用'.stab'打头的一类汇编指导命令表示,这些指导命令穿插在汇编代码中,这种调试信息格式叫'Stab',即符号表 (Symbol table)。XCOFF和a.out目标文件格式采用Stab调试信息格式。此外,GCC也能在COFF和ECOFF目标文件格式中产生Stab。如要 生成Stab调试信息,在GCC编译源文件时,打开编译选项'-gstabs+'(此选项将产生GNU调试器扩展的Stab的调试信息)或'- gstabs'。
汇编器处理'.stab'打头指导命令,把Stab中的调试信息填入'.o'文件的符号表和串表(string table)中,链接器合并所有'.o'文件生成只含有一个符号表和一个串表的可执行文件。调试器通过检索可执行文件中的符号表和串表来获得程序的调试信 息,下面分别介绍Stab的格式,GCC生成Stab和汇编链接器对Stab转换。
1 Stab的格式
Stab汇编指导命令有3种格 式:'.stabs'(string), '.stabn'(number)和'.stabd'(dot)。在MIPS机器上,GCC采用'.stabn'输出源程序语句行号的Stab调试信息, 而未使用'.stabd',因此,在MIPS机器上,GCC生成的带有Stab调试信息的汇编代码中只含'.stabs'和'.stabn'两种汇编指导 命令,'.stabs'和'.stabn'命令格式如下:
.stabs ″STRING″,TYPE,OTHER,DESC,VALUE
.stabn TYPE,OTHER,DESC,VALUE
下面说明Stab汇编指导命令的各域。
″STRING″的一般格式是:″NAME:SYM-DESC TYPE-INFO″
其中,NAME是由Stab表示的符号的名字,如果Stab表示是一个匿名对象,则NAME可省略,一般以一空格代替。SYM-DESC为一字母,它具体表示Stab所描述的是哪一类符号,例如:
SYM- DESC为'F',表示Stab描述的是全局函数;为'f'时,表示局部函数;为'G'时,表示全局变量。TYPE-INFO则表示数据类型信息,它可以 是Stab分配给已定义的数据类型的序号,表示对已定义的数据类型的引用;也可以是一串符号,用来定义一种新的数据类型,参见1.3数据类型定义。
OTHER没有使用,其值保持零。
DESC用编译开关'-gstabs+'编译源文件,DESC为源程序的语句行号;用编译开关'-gstabs'编译源文件,DESC为零。
VALUE可为一符号地址,或为自动变量在当前栈里相对帧指针的偏移量,或为寄存器变量所分配的寄存器的号码。
以下各小节将结合实例对Stab描述调试信息的格式作具体的阐述。
1.1 Stab描述程序结构
(1)源文件的名字和路径
在含有调试信息的汇编代码中,第一个Stab汇编指导命令指明所编译的源文件的名字,如果打开GCC编译开关'-gstabs+',还会指明该源文明所在的目录,例如:
.stabs ″usr/people/ycq/work / ″, 100, 0, 0, $Ltext( ) #100 is N-SO
.stabs ″example.c″, 100, 0, 0, $Ltext( )
其中TYPE为N-SO,表示该Stab描述的是源文件的名字或路径,$Ltext( )表示与该文件相对应的代码区的首地址。
(2)包含文件
描述包含文件的Stab指明随后出现的变量、函数等符号所要参考的源文件,调试器由此查找到定义该符号的源文件。STRING为被包含文件名,TYPE=N-SOL,VALUE为被包含文件代码区的首地址,如:
.stabs ″example.c″, 132, 0, 0, $Ltext1 #132 is N-SOL
(3)行号
行号表示汇编程序中的一段代码所对应的C源程序的语句行号。汇编指导命令采用'gstabn',TYPE=N-SLINE,DESC表示源程序的语句行号,VALUE为该语句行所对应的一段汇编代码的起始标号,例如:
.stabn 68, 0, 4, $LM6 #68 is N-SLINE
如果一源程序行所产生的汇编代码不连续,可用多条'.stabn'表示,而DESC为同一值。
(4) 函数 描述函数的Stab,其TYPE为N-FUN,VALUE为函数的符号地址。SYM-DESC=F表示该函数为全局函数,SYM-DESC=f表示该函数 的为局部函数,TYPE-INFO表示该函数的返回值的数据类型。下列为Stab描述局部函数func,其函数返回值为整型。
.stabs ″func: fl ″, 36, 0, 0, func #36 is N-FUN
(5)嵌套函数 嵌套函数是GNU C对标准C的扩充,Stab描述嵌套函数与描述一般函数的方式大致相同,区别是在描述嵌套函数时,在TYPE-INFO之后紧接包含该函数的最内层函数。
下面为一嵌套函数定义的例子,随后给出了其Stab描述。
int funx (int x)
{
int funy (int y)
{
int funz (int z){return x+y+z; }
return funz (x+y);

return funy (x);

生成的Stab为:
.stabs ″funz: fl, funy″, 36, 0, 0, funz.5
.stabs ″funy: fl, funx″, 36, 0, 0, funy.2
.stabs ″funx: Fl″, 36, 0, 0, funx
作用域的描述格式是:TYPE-INFO之后跟','号,然后被描述的函数名跟','号,最后是包含该函数定义的最内层函数的名字。
(6) 块结构 这里块结构是指C语言函数定义中表示块语句开始和结束的左、右括号。描述左括号的('{')Stab,其TYPE=N-LBRAC,VALUE为以 '$LBB'打头的汇编语句标号;描述右括号('}')的Stab,其TYPE=N-RBRAC,VALUE为以'$LBE'打头的汇编语句标号。汇编指 导命令为'.stabn'。例如:
.stabn 192, 0, 0, $LBB2 #192 is N-LBRAC
.stabn 224, 0, 0, $LBE2 #224 is N-RBRAC
1.2 Stab描述变量
在C语言里,根据变量所具有的不同的存储分配方式,可把变量分为:自动变量、全局变量、寄存器变量和静态变量。
(1)自动变量 自动变量存储在当前函数栈里,因此也叫 栈变量。Stab描述自动变量时,TYPE为N-LSYM,Stab描述自动变量在当前函数栈里相对于帧指针的偏移量,SYM-DESC被省缺,如:
.stabs ″x: l″, 128, 0, 0, -12 #128 is N-LSYM
(2)全局变量 全局变量的作用域不局限于定义它的那个文件,可为多个文件使用。Stab描述全局变量时,TYPE为N-GSYM,SYM-DESC为G,VALUE为零,调试器根据全局变量的外部符号获得其地址,如:char gvar='c';
生成的含Stab的汇编代码为:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值