找出程序的局部静态变量
全局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”。
打赏作者以资鼓励:
![]() | ![]() |