我希望能够通过部分编译来从C ++源文件集合中提取一些信息。我说部分编译,因为我无法访问它应链接的所有共享库。具体情况将在下面进一步解释。
在伪代码中,我(大致)有以下结构:
class AParent : public AClassFromSharedLib {
...
void setup(void);
void otherThings(void);
...
}
class AChild : public AParent {
...
void setup(void);
void moreStuff(void);
...
}
...
AParent::setup(void)
{
interestingFunction("foo");
interestingFunction("bar");
interestingFunction("baz");
somethingElse("cafe");
}
...
AChild::setup(void)
{
super::setup();
interestingFunction("dead");
interestingFunction("beef");
somethingElse("babe");
}
...
REGISTER_CLASS("SomeName", AChild);
我想要做的就是打印interestingFunction
setup()
方法调用路径中的AChild
参数REGISTER_CLASS
(以及通过SomeName:
"foo"
"bar"
"baz"
"dead"
"beef"
注册的其他对象)。
setup
我不在乎别的什么。只是对象层次结构和方法setup
才是我真正需要完成的任务。
我想告诉编译器,"删除此类中除.so
之外的所有方法,我将提供您需要的所有符号"。这可能吗?使用g ++ 4.4.x定位RedHat 5系统。
由于我无法访问要链接的.so
文件,因此我正在处理的代码本身就是编译为.so
。这样,链接器可以推迟解析符号直到稍后。这个文件被传递给做最终可以访问所有必要库并编译最终程序的东西。不幸的是,这个过程是隐藏的,所以我无法利用它进入图书馆。
我想我可以通过创建一个链接到我自己的-Os -fdata-sections -ffunction-sections -Wl,--gc-sections
的简单程序来提取一些信息,定义我关心的符号的简单实现,然后让我的调试程序实例化一些对象并调用一些方法。通过这种方式,我可以捕获有关我的程序的一些信息,而无需访问所有库。
我并不真正关心实际的实现,因此我可以轻松地为我不关心的符号提供虚拟实现,并为我关心的符号打印语句。问题是,我需要虚拟出数百个标题和数百个对象,类,函数等。事情很快就失控了。
我的第一个想法是利用gcc剥夺死代码的能力。我想如果我只从这个对象调用这个方法,它会看到所有其他代码都无法访问并丢弃这些符号。不幸的是,-flto
或其他任何类似的东西都不适合我。最有希望的标志似乎是-Wl,--unresolved-symbols=ignore-in-object-files
,但我无法尝试,因为我的编译器太旧了。
我也试过告诉链接器main()
,但这只会导致程序在运行时出现段错误,即使我没有使用{{1}}中任何未定义的符号。
我的伎俩很薄,我无法想到的其他事情。看起来解决方案是使用grep进行粗略解析并强制执行简单的编码标准(无变量,函数调用等),因此哑语解析器可以在某种程度上可靠地获取此信息。对于这个问题,感觉好像是一个更好的解决方案。