2011-08-25 24 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

相關問題