STL和发布/调试库混乱 [英] STL and release/debug library mess

查看:279
本文介绍了STL和发布/调试库混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了一些第三方。我使用它的共享库版本,因为库是大的(〜60MB),并被几个应用程序使用。



有一种方式在应用程序启动找到


$ b

b

暴露C ++接口的库。其中一个API方法返回 std :: vector< std :: string>



当我在调试模式下编译我的应用程序时,应该使用调试版本的库。相同的释放。如果使用不正确的库版本,应用程序崩溃。



根据gcc(请参阅 http:// gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html


但使用混合模式标准库
可能使用调试模式
或release-mode basic_string对象,
事情变得更复杂


PS 1



它看起来像Timbo的提案是一个可能的解决方案 - 使用不同的soname调试和发布库。那么,应该传递给./configure脚本以更改库soname?



2



我的问题不在链接时,而是在运行时。



3



这里是显示我面对的问题的问题。

解决方案

我相信你在你提供的链接上误读了文档。特别是,您误解了其目的 - 该部分的标题为目标,并描述了一些C ++调试库的假设设计以及这些设计的后果,以解释所做的实际设计选择。在引用的行之后的文本段描述了由假设实现引起的混乱,这些实现对发布模式和调试模式字符串有单独的设计。它继续说:


为此,我们不能轻易地为std :: basic_string类模板提供安全的迭代器,因为它存在


(或者说,提供一个特殊的调试版本的字符串迭代器是不可能的。)


...



使用libstdc ++调试模式的设计,隐藏调试和发行模式字符串与用户之间的差异。无法隐藏差异可能会导致不可预测的行为,因此,我们选择仅执行不需要ABI更改的basic_string更改。对用户的影响预计是最小的,因为有简单的替代方法(例如,__gnu_debug :: basic_string),并且我们从混合调​​试和发布编译的翻译单元的能力中获得的可用性好处是巨大的。


换句话说,GCC的libstdc ++中的调试和发布模式的设计已经拒绝了这个假设的实现,使用单独的字符串设计,特别是为了允许跨模式链接你担心如何避免的类型。



因此,你不应该有编译库一次,没有 -D_GLIBCXX_DEBUG (或与它,如果由于某种原因你更喜欢),并链接它与你的应用程序的任一模式。如果你有问题,它是由于某个地方的错误。 [但请看下面的编辑!这特定于 std :: string ,而不是其他容器!]



接受此回答后,我在 std :: vector crash 上回答了后续问题, / a>,并认识到这个答案的结论是不正确的。 GCC的libstdc ++用字符串做了聪明的事情来支持Per-use recompilation(其中给定容器对象的所有使用必须使用相同的标志来编译,但是在程序中使用相同的容器类不需要使用相同的标志),但这不是完全的单位编译,将提供您需要的交联能力相同的事情。特别是,文档说的交叉能力,


我们相信,这个级别的重新编译是不可能的,如果我们打算提供安全迭代器,让程序语义保持不变,并且在发布模式下不会退化。


在您的库界面之间传递容器,您将需要两个单独的库。老实说,对于这种情况,我发现最简单的解决方案只是将两个库安装到不同的目录(每个变体 - 一个,你会希望两者从你的主库目录分离)。或者,您可以重命名调试库文件,然后手动安装。



另一个建议是,你可能不是在调试模式下经常运行它。它可能值得编译和链接调试版本静态到您的应用程序,所以你不必担心安装多个动态库,并保持它们在运行时。


I'm using some 3rd party. I'm using it's shared library version, since the library is big (~60MB) and is used by several applications.

Is there a way at application startup to find out that release/debug version of library is used respectively for release/debug version of my application?

Longer description

The library which exposes C++ interface. One of API methods return std::vector<std::string>.

The problem when I compile my application in debug mode, debug version of the library should be used. Same for release. If incorrect version of the library is used application is crashed.

According to gcc (see http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html)

but with a mixed mode standard library that could be using either debug-mode or release-mode basic_string objects, things get more complicated

P.S. 1

It looks like proposal of Timbo is a possible solution - use different soname for debug and release libraries. So, what should be passed to ./configure script to change library soname?

P.S. 2

My problem is not at link time, but rather at run time.

P.S. 3

Here is question demonstrating problem I is facing with.

解决方案

I believe that you have misread the documentation at the link you provide. In particular, you've misunderstood its purpose -- that section is entitled "Goals", and describes a number of hypothetical designs for a C++ debug library and the consequences of those designs in order to explain the actual design choices that were made. The bits of text that follow the lines you quoted are describing the chaos that would result from a hypothetical implementation that had separate designs for release-mode and debug-mode strings. It goes on to say:

For this reason we cannot easily provide safe iterators for the std::basic_string class template, as it is present throughout the C++ standard library.

(Or, rephrasing that, providing a special "debug" version of string iterators is impossible.)

...

With the design of libstdc++ debug mode, we cannot effectively hide the differences between debug and release-mode strings from the user. Failure to hide the differences may result in unpredictable behavior, and for this reason we have opted to only perform basic_string changes that do not require ABI changes. The effect on users is expected to be minimal, as there are simple alternatives (e.g., __gnu_debug::basic_string), and the usability benefit we gain from the ability to mix debug- and release-compiled translation units is enormous.

In other words, the design of the debug and release modes in GCC's libstdc++ has rejected this hypothetical implementation with separate designs for the strings, specifically in order to allow cross-mode linking of the sort that you are worrying about how to avoid.

Thus, you should not have problems with compiling your library once, without -D_GLIBCXX_DEBUG (or with it, if for some reason you prefer), and linking it with either mode of your application. If you do have problems, it is due to a bug somewhere. [But see edit below! This is specific to std::string, not other containers!]

Edit: After this answer was accepted, I followed up in answering the follow-up question at std::vector crash, and realized that the conclusion of this answer is incorrect. GCC's libstdc++ does clever things with strings to support "Per-use recompilation" (in which all uses of a given container object must be compiled with the same flags, but uses of the same container class within a program need not be compiled with the same flags), but that is not the same thing as complete "Per-unit compilation" that would provide the cross-linking ability you need. In particular, the documentation says of that cross-linking ability,

We believe that this level of recompilation is in fact not possible if we intend to supply safe iterators, leave the program semantics unchanged, and not regress in performance under release mode....

Thus, if you're passing containers across your library interface, you will need two separate libraries. Honestly, for this situation I've found that the easiest solution is just to install the two libraries into different directories (one for each variant -- and you'll want both to be separate from your main library directory). Alternately, you can rename the debug library file and then install it manually.

As a further suggestion -- you're presumably not running this in debug mode very often. It may be worth only compiling and linking the debug version statically into your application, so you don't have to worry about installing multiple dynamic libraries and keeping them straight at runtime.

这篇关于STL和发布/调试库混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆