静态链接破坏了 Windows 上的调试可执行文件(mingw)
我们的 C++ 项目使用混合动态 (Qt) 和静态(ffmpeg、portaudio)库。目前,我正在尝试将其移植到 Windows,并且 mingw(通过 QtCreator)生成的调试可执行文件拒绝启动(错误是这样的不是有效的可执行文件)。具有相同链接的发布可执行文件启动(但有一些我想调试的问题)。
为了缩小问题的可能原因,我创建了一个虚拟项目,该项目什么也不做,只是链接到同一组库,并且它具有完全相同的问题。只要我禁用到两个静态库的链接,调试可执行文件就可以工作,一旦我启用其中任何一个,调试可执行文件就会被破坏。
我还没有尝试构建 ffmpeg 和 portaudio 的 dll 版本,但我想了解这种情况出了什么问题。
Our C++ project uses mixed dynamic (Qt) and static (ffmpeg, portaudio) libraries. At the moment I'm trying to port it to windows and the debug executable produced by mingw (via QtCreator) refuses to start (the error is such-and-such is not a valid executable). The release executable with the same linkage starts (but has some problems I would like to debug).
To narrow down the possible cause of the problem I made a dummy project that does nothing, just links to the same set of libraries and it has exactly the same problem. As long as I disable linking to both static libraries debug executable works, as soon as I enable any one of them the debug executable is broken.
I haven't tried building dll versions of ffmpeg and portaudio yet, but I would like to understand what's going wrong with the case as it is.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为某些 Qt 下载中包含的 MinGW 包中的 ld 链接器存在严重错误。
MinGW 4.4.0 包中包含的 ld 链接器在放置
.debug_pubtypes
部分(存储符号或某些调试信息的位置)的默认链接器脚本中存在一个错误。链接器脚本导致该部分被放置在加载程序不喜欢的虚拟地址(或类似的地址)。有时 - 如果图像中没有符号,或者符号足够小(或者可能有其他因素),则问题不会出现。您有几个选项:
-T
选项指定正确的链接器脚本以 ld这是 ld 2.21 中的默认链接器脚本,如果您将其传递到您拥有的版本,它应该可以工作(不幸的是,我的注释没有说明有问题的 ld 的版本号是什么 - 如果您可以对此发表评论)这样我就可以更新我的笔记,我会很感激)。
我不介意告诉你,我必须经历大约一周的痛苦才能解决这个问题。对于它认为可执行文件无效的原因,Windows 根本没有提供任何真正的帮助,并且即使使用“Windows 调试工具”中的 cdb 或 WinDBG 进行调试也没有什么帮助。 Windows 似乎从 NT 内核的加载程序内部深处就确定 PE 无效,并且没有提供我能找到的任何有关原因的信息(如果能在 PE 中放入一些东西就好了)事件日志或其他)。
我最终使用 Wine 的(!!)跟踪工具解决了这个问题。我想知道 Windows 的“检查”版本是否会提供有关该问题的更多信息,但我在下载和安装该版本时遇到了麻烦。
This is because of a nasty bug in the ld linker in the MinGW package that's included in some Qt downloads.
The ld linker that's included with the MinGW 4.4.0 package has a bug in the default linker script for placement of the
.debug_pubtypes
section, which is where symbols or some debug information gets stored. The linker script causes that section to get placed at a virtual address that the loader doesn't like (or something like that). Sometimes - if you don't have symbols in the image, or if the symbols are small enough (or maybe there's some other factor) the problem doesn't show up.You have a couple of options:
-T <scriptfile>
option to specify a correct linker script to ldHere's the default linker script from ld 2.21, which should work if you pass it in to the version you have (unfortunately my notes don't say what the version number of the ld with the problem is - if you could drop a comment about that so I can update my notes, I'd appreciate it).
I don't mind telling you that I had to go through about a week of pain to figure this out. Windows doesn't give any real help at all about the reason it thinks the executable is invalid, and debugging - even with cdb or WinDBG from the "Debugging Tools for Windows" - is little help. Windows seems to make the determination that the PE is invalid from deep within the bowels of the loader in the NT kernel, and doesn't give any information that I could find about the reason (it would have been nice to have something put into the event log or something).
I ultimately figured out this problem using Wine's (!!) tracing facility. I wonder if the 'checked' version of Windows would give more information about the problem, but I was having a hell of a time getting that downloaded and installed.