2011-08-25 3 views
1

C++ 프로젝트는 혼합 동적 (Qt) 및 정적 (ffmpeg, portaudio) 라이브러리를 사용합니다. 지금은 Windows로 이식하려고하는데 mingw (QtCreator를 통해)가 생성 한 디버그 실행 파일은 시작하기를 거부합니다 (오류가 발생하면 유효한 실행 파일이 아닙니다). 같은 링키지로 실행 가능한 릴리즈가 시작됩니다 (그러나 디버깅하고 싶은 몇 가지 문제가 있습니다).정적 연결이 Windows에서 디버그 실행 파일을 깨뜨림

문제의 가능한 원인을 좁히려면 아무 것도하지 않는 더미 프로젝트를 만들었고 동일한 라이브러리 세트에 연결하면 정확히 동일한 문제가 발생합니다. 제가 두 정적 라이브러리 디버깅 실행 파일에 링크를 해제하는 한, 디버그 실행 파일이 깨진 즉시 그 중 하나를 사용할 수있게됩니다.

저는 ffmpeg 및 portaudio의 dll 버전을 아직 구축하지 않았지만이 경우에 어떤 문제가 있는지 이해하고 싶습니다.

답변

1

이것은 일부 Qt 다운로드에 포함 된 MinGW 패키지의 ld 링커에있는 불쾌한 버그 때문입니다.

MinGW 4.4.0 패키지에 포함 된 ld 링커에는 기호 또는 디버그 정보가 저장되는 .debug_pubtypes 섹션을 배치하기위한 기본 링커 스크립트에 버그가 있습니다. 링커 스크립트는 해당 섹션이 로더가 좋아하지 않는 가상 주소 (또는 이와 비슷한)에 배치되도록합니다. 때로는 - 이미지에 기호가 없거나 기호가 충분히 작 으면 (또는 다른 요인이있을 수 있음) 문제가 나타나지 않습니다.

  • 이는 MinGW 4.5.2 작품과 함께 제공 LD (버전 2.21의 최신 버전으로
  • 업그레이드를 LD하는 올바른 링커 스크립트를 지정 -T <scriptfile> 옵션을 사용

    당신은 몇 가지 옵션이있다 벌금). 여기

당신은 당신이 가지고있는 버전에 전달하면 작동합니다 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.*) 
    } 
} 

나는 이것을 알아 내기 위해 약 1 주일 정도의 고통을 겪어야한다는 것을 알려줍니다. Windows는 실행 파일이 유효하지 않다고 생각하는 이유에 대해 전혀 도움을주지 않으며 "Windows 용 디버깅 도구"의 cdb 또는 WinDBG를 사용하는 경우에도 거의 도움이되지 않습니다. Windows는 PE가 NT 커널의 로더 내부 깊숙한 곳에서 유효하지 않다는 결론을 내린 것으로 보인다. 이유에 대해 알 수있는 정보를 제공하지 않는다. 이벤트 로그 또는 뭔가).

나는 Wine (추적) 기능을 사용하여이 문제를 궁극적으로 알아 냈습니다. Windows의 '확인 된'버전이 문제에 대한 자세한 정보를 제공하는지 궁금하지만, 다운로드하여 설치하는 데 지옥이 생기고 있습니다.

+0

덕분에 많은 스타가되었습니다. – artm

+0

나는 ld 2.19.1을 포함하는 mingw 4.4를 가진 QtCreator 2.2.1을 가지고있다. – artm

+0

흠 ... 테스트 바이너리가 정적으로 링크 될 때 실행되지만 프로젝트 자체는 여전히 실행되지 않습니다. – artm

관련 문제