从命令行检索全局变量值

时间:2012-03-14 21:40:04

标签: c linux posix shared-objects

在一个特定项目中,我们尝试将版本信息嵌入到共享对象文件中。我们希望能够使用一些标准的linux工具来解析共享对象,以确定自动化测试的版本。 目前我有“const int plugin_version = 14;”。我可以使用'nm'和'objdump'来验证它是否存在:

00000000000dcfbc r plugin_version
但是,我似乎无法从命令行轻松获取该变量的值。我想有一个POSIX工具可以显示全局变量的初始化值。我已经考虑过将变量的格式用作信息本身,即plugin_version_14,但这似乎是一个巨大的黑客攻击。遗憾的是,在文件名中嵌入信息不是一种选择。欢迎任何其他建议。

6 个答案:

答案 0 :(得分:2)

您可以将其嵌入字符串

“MAGIC MARKER STRING VERSION:4.56 END OF MAGIC”然后只需在文件中查找“MAGIC MARKER STRING”并提取其后的版本信息。

如果你把它作为标准,你可以轻松地使命令行工具在你的所有软件上找到这些嵌入的字符串。

如果你还要求它也是一个int,一个小的魔法会构造int和magic字符串,以确保它们永远不会同步。

答案 1 :(得分:1)

我认为有几种选择。

我的第一直觉是确保版本信息存在于ELF文件的各自部分中。您可以使用objdump -s -j 部分名称 / bin / whatever。 这当然取决于objdump可用。

或者你可以做Keith建议的,只需使用'strings',以及一个神奇的标记字符串。这感觉有点hackish,但应该工作得很好。

最后,为什么不添加--version命令行选项?然后,您可以随意存储版本信息,并使用一个工具轻松检索它,该工具肯定会安装在任何具有您软件的系统上。

答案 2 :(得分:0)

我过去使用的一个糟糕的黑客是将版本信息嵌入到变量名中,因此nm将显示:

00000000000dcfbc r plugin_version_14

答案 3 :(得分:0)

为什么不编写自己的工具来在C / C ++中获取该版本?您可以使用dlopen,然后使用dlsym来获取符号并将其值打印到标准输出。这样您还可以验证符号是否已存在。对我来说看起来像20到30行代码,你的生命大概是20分钟。)

我知道问题是关于命令行的,但是自己编写这样的工具应该很容易(特别是如果这样的命令行工具不存在的话)。

答案 4 :(得分:0)

如果未剥离二进制文件,则可以使用gdb打印变量。 (我只是尝试编写gdb脚本,但是如果stdin不是tty似乎拒绝工作,也许期望会做这个工作?)

答案 5 :(得分:0)

如果您可以接受使用python,这可能会有所帮助:

import struct
import sys
import subprocess

if __name__ == '__main__':
    so = sys.argv[1]
    sym = sys.argv[2]

    addr = subprocess.check_output('nm %s | grep %s' % (so, sym), shell=True)
    addr = int(addr.split()[0], 16)

    so_file = open(so)
    so_file.seek(addr)
    data = so_file.read(4)

    print struct.unpack('@i', data)[0]

免责声明:此脚本不会执行任何错误检查(如果您喜欢它,我相信您可以提出一些错误检查;))。它还假设您正在读取一个4字节的原生int值。

$ cat global.c 
const int plugin_version = 14;
$ python readsym.py global.so plugin_version
14