全局static变量,可以使用gdb的“info variables”找出,且可以列出变量所在文件(有符号库的情况下)。但是函数局部的static变量就比较麻烦了。 先看一个例子: ```c #include #include 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”。