我们的C ++项目使用混合dynamic(Qt)和静态(ffmpeg,portaudio)库。 目前我正试图将其移植到Windows,由mingw(通过QtCreator)生成的debugging可执行文件拒绝启动(错误是这样的,而且这不是一个有效的可执行文件)。 具有相同链接的发布可执行文件开始(但有一些问题,我想debugging)。
为了缩小问题的可能原因,我做了一个虚拟项目,它什么都不做,只是链接到相同的一组库,它有完全相同的问题。 只要我禁用链接到这两个静态库debugging可执行的作品,只要我启用其中任何一个debugging可执行文件被打破。
我还没有尝试build立ffmpeg和portaudio的DLL版本,但我想了解情况是怎么回事,因为它是。
这是因为MinGW包中的ld链接器中的一个令人讨厌的bug,包含在一些Qt下载中。
MinGW 4.4.0包中包含的ld连接器在缺省链接描述文件中存在一个错误,用于放置.debug_pubtypes
部分,这是符号或某些调试信息的存储位置。 链接器脚本导致该部分放置在加载器不喜欢的虚拟地址(或类似的东西)。 有时候,如果图像中没有符号,或者符号足够小(或者还有其他因素),问题就不会出现。
你有几个选择:
-T <scriptfile>
选项为ld指定正确的链接器脚本 这里是来自ld 2.21的默认链接器脚本,如果你将它传递给你的版本,这应该是可行的(不幸的是我的笔记没有说出问题的ld的版本号是什么 – 如果你可以放弃关于该问题的评论所以我可以更新我的笔记,我会很感激它)。
/* Default linker script, for normal executables */ OUTPUT_FORMAT(pei-i386) SEARCH_DIR("/c/temp/gcc/dest/i686-pc-mingw32/lib"); SEARCH_DIR("/c/temp/gcc/dest/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); SECTIONS { /* Make the virtual address and file offset synced if the alignment is lower than the target page size. */ . = SIZEOF_HEADERS; . = ALIGN(__section_alignment__); .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : { *(.init) *(.text) *(SORT(.text$*)) *(.text.*) *(.glue_7t) *(.glue_7) ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); *(.fini) /* ??? Why is .gcc_exc here? */ *(.gcc_exc) PROVIDE (etext = .); *(.gcc_except_table) } /* The Cygwin32 library uses a section to avoid copying certain data on fork. This used to be named ".data". The linker used to include this between __data_start__ and __data_end__, but that breaks building the cygwin32 dll. Instead, we name the section ".data_cygwin_nocopy" and explictly include it after __data_end__. */ .data BLOCK(__section_alignment__) : { __data_start__ = . ; *(.data) *(.data2) *(SORT(.data$*)) *(.jcr) __data_end__ = . ; *(.data_cygwin_nocopy) } .rdata BLOCK(__section_alignment__) : { *(.rdata) *(SORT(.rdata$*)) ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = .; *(.rdata_runtime_pseudo_reloc) ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; } .eh_frame BLOCK(__section_alignment__) : { *(.eh_frame) } .pdata BLOCK(__section_alignment__) : { *(.pdata) } .bss BLOCK(__section_alignment__) : { __bss_start__ = . ; *(.bss) *(COMMON) __bss_end__ = . ; } .edata BLOCK(__section_alignment__) : { *(.edata) } /DISCARD/ : { *(.debug$S) *(.debug$T) *(.debug$F) *(.drectve) *(.note.GNU-stack) *(.gnu.lto_*) } .idata BLOCK(__section_alignment__) : { /* This cannot currently be handled with grouped sections. See pe.em:sort_sections. */ SORT(*)(.idata$2) SORT(*)(.idata$3) /* These zeroes mark the end of the import list. */ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); SORT(*)(.idata$4) __IAT_start__ = .; SORT(*)(.idata$5) __IAT_end__ = .; SORT(*)(.idata$6) SORT(*)(.idata$7) } .CRT BLOCK(__section_alignment__) : { ___crt_xc_start__ = . ; *(SORT(.CRT$XC*)) /* C initialization */ ___crt_xc_end__ = . ; ___crt_xi_start__ = . ; *(SORT(.CRT$XI*)) /* C++ initialization */ ___crt_xi_end__ = . ; ___crt_xl_start__ = . ; *(SORT(.CRT$XL*)) /* TLS callbacks */ /* ___crt_xl_end__ is defined in the TLS Directory support code */ ___crt_xp_start__ = . ; *(SORT(.CRT$XP*)) /* Pre-termination */ ___crt_xp_end__ = . ; ___crt_xt_start__ = . ; *(SORT(.CRT$XT*)) /* Termination */ ___crt_xt_end__ = . ; } .tls BLOCK(__section_alignment__) : { ___tls_start__ = . ; *(.tls) *(.tls$) *(SORT(.tls$*)) ___tls_end__ = . ; } .endjunk BLOCK(__section_alignment__) : { /* end is deprecated, don't use it */ PROVIDE (end = .); PROVIDE ( _end = .); __end__ = .; } .rsrc BLOCK(__section_alignment__) : { *(.rsrc) *(SORT(.rsrc$*)) } .reloc BLOCK(__section_alignment__) : { *(.reloc) } .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) } .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section. Unlike other targets that fake this by putting the section VMA at 0, the PE format will not allow it. */ /* DWARF 1.1 and DWARF 2. */ .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) } .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) } .debug_pubtypes BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubtypes) } /* DWARF 2. */ .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) } .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) } .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) } .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) } .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) } .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions. */ .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) } .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) } .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) } .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) } /* DWARF 3. */ .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) } /* DWARF 4. */ .debug_types BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_types) *(.gnu.linkonce.wt.*) } }
我不介意告诉你,为了解决这个问题,我必须经历一周的痛苦。 对于Windows认为可执行文件无效的原因,Windows并没有提供任何真正的帮助,调试 – 甚至在“Windows调试工具”中使用cdb或WinDBG也没有什么帮助。 Windows似乎决定PE在NT内核的加载器的内部是无效的,并且没有给出任何我能找到的有关这个原因的信息(如果有一些东西放在事件日志或其他)。
我最终使用Wine的(!!)追踪工具发现了这个问题。 我不知道Windows的“检查”版本是否会提供更多关于这个问题的信息,但是我却花了一些时间去下载和安装。