【问题标题】:Specify the type residing in a specific address指定驻留在特定地址的类型
【发布时间】:2013-11-03 20:02:27
【问题描述】:

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

【问题讨论】:

  • 没有办法知道这一点,至少没有调试符号。
  • 这是否存在于任何其他语言中?怎么样?
  • 甚至内置C函数,如printf()scanf()等。 al,解析 格式说明符(例如“%s, %f, %d”)以了解正在传递的内容。同意@Jocke,除了传递一个论据来说明它们是什么之外别无他法。
  • 如果你使用gcc,你可以用-g标志编译,用调试符号编译。调试符号是二进制文件中的额外数据,其中包含变量类型、名称等信息。

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


【解决方案1】:

正如 cmets 所提到的,除非您有调试符号,否则您无法获得类型。但如果你确实有符号,那么你可以使用 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 --静默类型 从 /home/ubuntu/types 读取符号...完成。 (gdb) 类型 = int ubuntu@ubuntu:~$ echo ptype f | gdb --静默类型 从 /home/ubuntu/types 读取符号...完成。 (gdb) 类型 = 浮点数 ubuntu@ubuntu:~$ echo ptype d | gdb --静默类型 从 /home/ubuntu/types 读取符号...完成。 (gdb) 类型 = 双 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 的表达式然后计算我们感兴趣的地址和紧随其后的地址之间的差异。注意地址是十六进制的,所以我们需要用ibase 参数告诉bc${var^^} bash 扩展还将十六进制数字 a-f 转换为大写,因为 bc 需要这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2013-11-10
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多