stabs: c语言如何使用stabs存放debug信息,以及如何使用stabs查找函数, stacktrace 如何实现

本文详细介绍了C语言中stabs格式的调试信息,包括其作用、GNU C编译器如何生成stabs、stabs在symbol table中的组织方式,以及如何通过stabs查找IP对应的文件名、行号和函数名。此外,文章还探讨了C语言backtrace的实现原理和stabs在查找IP地址对应源代码信息时的疑问。
摘要由CSDN通过智能技术生成

stabs 已经被 DWARF 替代......

stabs是什么

Stabs (Symbol Table String) refers to a format for information that describes a program to a debugger.

GNU C compiler如何使用stabs

overview

The GNU C compiler compiles C source in a .c file into assembly language in a .s file, which the assembler translates into a .o file, which the linker combines with other .o files and libraries to produce an executable file.

With the ‘-g’ option, GCC puts in the .s file additional debugging information, which is slightly transformed by the assembler and linker, and carried through into the final executable. This debugging information describes features of the source file like line numbers, the types and scopes of variables, and function names, parameters, and scopes.

The assembler adds the information from stabs to the symbol information it places by default in the symbol table and the string table of the .o file it is building. The linker consolidates the .o files into one executable file, with one symbol table and one string table. Debuggers use the symbol and string tables in the executable as a source of debugging information about the program.

To generate stabs now, we need -gstabs option since DWARF has been used for debug information by default now.

$ gcc -gstabs tst.c  # generate stabs debug info
$ gcc -g tst.c # generate DWARF

$ readelf --debug-dump=info a.out  # check which version is used in executable file
Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0x7f (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)

The format of stab

.stabs "string",type,other,desc,value

The number in the type field gives some basic information about which type of stab this is (or whether it is a stab, as opposed to an ordinary symbol). Each valid type number defines a different stab type; further, the stab type defines the exact interpretation of, and possible values for, any remaining string, desc, or value fields present in the stab.

the format of symbol table entries and how stab assembler directives map to them

Each time the assembler encounters a stab directive, it puts each field of the stab into a corresponding field in a symbol table entry of its output file. If the stab contains a string field, the symbol table entry for that stab points to a string table entry containing the string data from the stab. Assembler labels become relocatable addresses. Symbol table entries in a.out have the format:

struct internal_nlist {
  unsigned long n_strx;         /* index into string table of name */
  unsigned char n_type;         /* type of symbol */
  unsigned char n_other;        /* misc info (usually empty) */
  unsigned short n_desc;        /* description field */
  bfd_vma n_value;              /* value of symbol */
};

If the stab has a string, the n_strx field holds the offset in bytes of the string within the string table. The string is terminated by a NUL character. If the stab lacks a string (for example, it was produced by a .stabn or .stabd directive), the n_strx field is zero.

Symbol table entries with n_type field values greater than 0x1f originated as stabs generated by the compiler (with one random exception). The other entries were placed in the symbol table of the executable by the assembler or the linker.

picture for stabs workflow

example

source code

-----------------------
# tst.h

#ifndef INC_TST_H
#define INC_TST_H

static inline int inb()
{
        return 5;
}
#endif
-----------------------
# tst.c

#include <tst.h>

void func3()
{
        int a = 2;
        a = inb();
        a += 1;
}

int func2(char c)
{
        int a = 1;
        a += c;
        func3();
        a = 2;
}

char func(int i)
{
        char c = 'a';
        func2(c);
        c = 'b';
}

int main()
{
        int a;

        a = 1;
        func(a);
        a = 2;

        return 0;
}

-----------------------
# tst2.c

char t2_func(int i)
{
        char c = 'a';
        func2(c);
}


-----------------------
# tst3.c

char t3_func(int i)
{
        char c = 'a';
        func2(c);
}

stabs

$ gcc -gstabs -I./ tst*.c -S

$ cat tst.s # each tst*.c has its own .s file
	.file	"tst.c"
	.stabs	"tst.c",100,0,2,.Ltext0
	.text
.Ltext0:
	.stabs	"gcc2_compiled.",60,0,0,0
	.stabs	"int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0
	.stabs	"char:t(0,2)=r(0,2);0;127;",128,0,0,0
	.stabs	"long int:t(0,3)=r(0,3);-0;4294967295;",128,0,0,0
	.stabs	"unsigned int:t(0,4)=r(0,4);0;4294967295;",128,0,0,0
	.stabs	"long unsigned int:t(0,5)=r(0,5);0;-1;",128,0,0,0
	.stabs	"__int128:t(0,6)=r(0,6);0;-1;",128,0,0,0
	.stabs	"__int128 unsigned:t(0,7)=r(0,7);0;-1;",128,0,0,0
	.stabs	"long long int:t(0,8)=r(0,8);-0;4294967295;",128,0,0,0
	.stabs	"long long unsigned int:t(0,9)=r(0,9);0;-1;",128,0,0,0
	.stabs	"short int:t(0,10)=r(0,10);-32768;32767;",128,0,0,0
	.stabs	"short unsigned int:t(0,11)=r(0,11);0;65535;",128,0,0,0
	.stabs	"signed char:t(0,12)=r(0,1
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值