指定驻留在特定地址中的类型

时间:2013-11-03 20:02:28

标签: c bash memory-management reflection linker-scripts

我使用Bash来获取c程序变量的地址。如何知道地址是否与整数,浮点数或双变量有关?

1 个答案:

答案 0 :(得分:1)

正如所提到的注释,除非您有调试符号,否则无法获取类型。但如果你有符号,那么你可以使用GDB。考虑一下这个程序:

#include <stdio.h>

static int i = 42;
static float f = 42.1;
static double d = 42.2;

int main (int argc, char **argv) {
    printf("i=%d, f=%f, d=%f\n", i, f, d);
    return (0);
}

如果您按如下方式编译它:

gcc -g -o types types.c

然后你可以得到这样的变量类型:

ubuntu@ubuntu:~$ echo ptype i | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = int
ubuntu@ubuntu:~$ echo ptype f | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = float
ubuntu@ubuntu:~$ echo ptype d | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = double
ubuntu@ubuntu:~$

如果您只有符号表而没有完整的调试信息,即二进制文件是用-g编译的,然后由strip -d处理,那么您可以做的最好就是得到给定的大小使用二进制转储实用程序的对象,例如nmobjdumpreadelf

使用nm

ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' i$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' f$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu@ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' d$' | cut -d' ' -f1)
ubuntu@ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
8
ubuntu@ubuntu:~$ 

其工作原理如下:

  • nm -n列出符号表,地址按数字顺序
  • grep -A1 ' i$使用紧随其后的行过滤我们感兴趣的符号。请注意,这是一个正则表达式搜索,用于精确查找符号i,而不是其他任何内容
  • cut -d' ' -f1仅列出地址
  • read addr next_addr将地址分为两个变量
  • 管道传输到bc的表达式然后计算我们感兴趣的地址和紧随其后的地址之间的差异。请注意,地址是十六进制的,因此我们需要使用bc参数告诉ibase。此外,${var^^} bash扩展会将十六进制数字a-f转换为大写,因为bc需要这样做。