2012-03-14 83 views
2

在一个特定项目中,我们试图将版本信息嵌入到共享对象文件中。我们希望能够使用一些标准的linux工具来解析共享对象,以确定自动化测试的版本。 目前我有“const int plugin_version = 14;”。我可以使用“纳米”和“objdump的”,并确认它的存在:从命令行检索全局变量值

00000000000dcfbc r plugin_version 

我没有,但是,似乎可以能够通过命令行轻松地获得该变量的值。我想到会有一个POSIX工具来显示全局变量的初始化值。我已经设想使用变量的格式作为信息本身,即plugin_version_14,但这似乎是一个巨大的破解。不幸的是,将信息嵌入文件名不是一种选择。欢迎任何其他建议。

回答

0

,我已经在过去使用的一个可怕的黑客是嵌入在变量名的版本信息,所以纳米将显示:

00000000000dcfbc r plugin_version_14 
+0

这最终成为我们的解决方案。 – QBasicer 2012-03-21 00:37:37

2

你可以把它嵌入一个字符串

“魔术刻印的字符串形式:4.56 MAGIC结束”然后就找“魔术刻印STRING”的文件中,并提取后,自带的版本信息。

如果您将其作为标准,您可以轻松地使命令行工具在所有软件上查找这些嵌入字符串。

如果你需要它也是一个int,一个小宏将构造int和magic字符串以确保它们永远不会不同步。

+0

我上面的人决定他们不想通过寻找字符串的文件进行挖掘。我其实考虑使用XML。 – QBasicer 2012-03-21 00:39:01

1

有几个我觉得选择。

我的第一本能是确保版本信息存放在ELF文件中它自己的部分。您可以使用objdump -s -j 部分的名称/bin/whatever。 这当然依赖于objdump。

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

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

+0

它实际上是一个插件,所以它是一个共享对象文件,并试图确定脚本中的哪个可执行文件用于加载它。 – QBasicer 2012-03-21 00:37:08

+0

它/可能/有可能​​使用一些链接器欺骗来获得也是可执行的共享库。 – 2012-03-21 08:39:37

0

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

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

+0

我曾经提出过这个问题,实际上这是我的第一选择,但他们不想支持另一个工具。 – QBasicer 2012-03-15 15:39:00

0

如果二进制文件没有被去除,你可以用gdb打印变量。 (我只是试图脚本gdb,但它似乎拒绝工作,如果stdin不是一个tty,也许期望会做这项工作?)

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 
+0

不幸的是,我们不能指望在机器上可用的Python :( – QBasicer 2012-03-21 00:37:56