2011-08-25 79 views
1

我们的C++项目使用混合动态(Qt)和静态(ffmpeg,portaudio)库。目前我试图将它移植到windows上,并且由mingw(通过QtCreator)生成的调试可执行文件拒绝启动(错误是这样 - 并且这不是有效的可执行文件)。具有相同链接的发布可执行文件开始(但有一些问题,我想调试)。静态链接断开Windows上的调试可执行文件(mingw)

为了缩小问题的可能原因,我做了一个不做任何事的虚拟项目,只是链接到同一组库,它有完全相同的问题。只要我禁用链接到两个静态库调试可执行的作品,只要我启用它们中的任何一个,调试可执行文件就会被破坏。

我还没有尝试过建立ffmpeg和portaudio的dll版本,但我想知道这是怎么回事,因为它是。

回答

1

这是因为某些Qt下载中包含的MinGW包中的ld链接器中存在一个令人讨厌的错误。

MinGW 4.4.0包中包含的ld连接器在默认链接描述文件中存在一个缺陷,用于放置.debug_pubtypes部分,该部分是符号或某些调试信息的存储位置。链接器脚本导致该部分放置在加载器不喜欢的虚拟地址处(或类似的地址)。有时候 - 如果图像中没有符号,或者符号足够小(或者还有其他因素),则问题不会显示出来。

你有两个选择:

  • 使用-T <scriptfile>选项来指定一个正确的链接脚本到LD
  • 升级随附MinGW的4.5.2工程LD(2.21版本的更新版本精细)。

下面是从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的“检查”版本是否会提供更多关于这个问题的信息,但我有一段时间让下载和安装。

+0

非常感谢,你是明星! – artm

+0

我有QtCreator 2.2.1和mingw 4.4,其中包括ld 2.19.1。 – artm

+0

嗯......虽然测试二进制文件现在在静态链接时运行,但项目本身仍然没有。 – artm

相关问题