C++ Debug笔记——在库和main中使用相同的类名引发的惨案

阅读量: searchstar 2023-08-03 21:16:54
Categories: Tags:

背景

程序A 动态链接 库B,库B中有一个内部使用的Timers类,程序A中也有一个内部使用的Timers,两者都没有被置于namespace中。

现象

Release编译时一切正常,Debug编译时库B中的Timers类的构造函数没有被执行。

调试

在调用Timers的构造函数的地方尝试按F11跳转到库B中的Timers的构造函数中时,却跳转到了程序A内部使用的Timers中。

分析

库B在编译时,看不到程序A中的Timers,因此调用库B中的Timers却实际调用程序A中的Timers的原因肯定是链接的时候发生了符号覆盖。也就是说,库B中的Timers和程序A中的Timers中的构造器的signature一样的话,它们对应的符号也是一样的,而由于程序A和库B是动态链接的,因此链接的时候不会提示符号冲突,而是直接使用了程序A中的符号,这就导致了库B中的代码想调用库B中的Timers的构造函数,却意外调用了程序A中具有相同符号的Timers的构造函数。这也解释了为什么release编译时没有问题,因为此时Timers的构造器和其他method都被内联了,没有符号。

解决方案

把库B中的所有代码都包在一个B自己的namespace里。这样B里的所有符号都是以这个全局唯一的namespace为前缀的,就不会跟其他库或者程序里的符号重名了。