FAIRYFAR-INTERNAL
 
  FAIRYFAR-INTERNAL  |  SITEMAP  |  ABOUT-ME  |  HOME  
找出程序的局部静态变量

全局static变量,可以使用gdb的“info variables”找出,且可以列出变量所在文件(有符号库的情况下)。但是函数局部的static变量就比较麻烦了。

先看一个例子:

snippet.c
#include <sys/syscall.h>
#include <stdio.h>
 
void fun()
{
    static int ls_pid1 = 0;  // 初始化为0
    int pid1 = syscall(SYS_gettid);
    ls_pid1 = pid1;
    printf("%d\n", ls_pid1);
}
 
int main()
{
    int pid = syscall(SYS_gettid);
    static int ls_pid = 1;  // 初始化非0
    ls_pid = pid;
    printf("%d\n", ls_pid);
    fun();
    return 0;
}

以上代码有两个局部static变量:ls_pid1和ls_pid1。

方法一:gdb

使用-O0和-g编译:

[yz@test-4 ~]$ gcc ls_demo.c -lpthread -O0 -g -o ls_demo

使用gdb,可以找出static变量:

[yz@test-4 ~]$ gdb ./ls_demo
(peda)$ info variables 
All defined variables:

Non-debugging symbols:
……
0x000000000060103c  ls_pid
0x0000000000601040  __TMC_END__
0x0000000000601040  __bss_start
0x0000000000601040  _edata
0x0000000000601040  completed
0x0000000000601044  ls_pid1
0x0000000000601048  _end

本方法需要注意:

  • 如果优化级别大于0,则失效了。即如果优化编译选项大于等于O1,以上方法失效。
  • 引入的库中如果有全局变量,也会混杂在一起,无法区分哪些是我们代码的变量。

方法二:objdump

使用-O0和-g编译:

[yz@test-4 ~]$ gcc ls_demo.c -lpthread -O0 -g -o ls_demo

使用objdump,可以找出部分static变量:

[yz@test-4 ~]$ objdump ./ls_demo -t | grep ".\data"
0000000000400680 l    d  .rodata	0000000000000000              .rodata
0000000000601038 l    d  .data	0000000000000000              .data
000000000060103c l     O .data	0000000000000004              ls_pid.2430
0000000000601038  w      .data	0000000000000000              data_start
0000000000601040 g       .data	0000000000000000              _edata
0000000000601038 g       .data	0000000000000000              __data_start
0000000000400688 g     O .rodata	0000000000000000              .hidden __dso_handle
0000000000400680 g     O .rodata	0000000000000004              _IO_stdin_used
0000000000601040 g     O .data	0000000000000000              .hidden __TMC_END__

本方法需要注意:

  • 同样地,如果优化编译选项大于等于O1,以上方法失效。
  • 引入的库中如果有全局变量,也会混杂在一起,无法区分哪些是我们代码的变量。
  • 无法列出初始化为0或者没有初始化的局部static变量。

该方法也有好处:

  • 静态变量会在变量名称后面添加一个数据,该数字是用来区分同名变量的,例如上例中的“ls_pid.2430”。


打赏作者以资鼓励:
移动端扫码阅读: