DLL молча игнорируется, хотя ссылки на библиотеки - PullRequest
1 голос
/ 09 июля 2020

Я использую третью часть DLL, которую успешно использовал много лет. Теперь компоновщик связывает библиотеку dll без жалоб, но exe не загружает dll.

Недавно я обновился с 32-битной до 64-битной cygwin. Я делаю кросс-компиляцию mingw на 32 бита. Я пытаюсь использовать FTDI USB interface FTD2XX dll.

У меня версия 2.04.06 FTD2XX lib, .h и dll. Я много лет успешно использовал эту dll, но со старыми версиями cygwin и mingw. Недавно обновлено до cygwin64.

Похоже, что приложение без жалоб связывается с FTD2XX.lib. Но когда я запускаю приложение, кажется, что оно не ищет и не загружает FTD2XX.dll. Приложение запускается, но вылетает, как только пытается вызвать что-то в DLL FTD2XX.

Я создал простой hello_dll.dll для параллельного тестирования. Это работает. Приложение. c выполняет вызовы как hello_dll.dll, так и ftd2xx.dll. Запускается без жалоб, успешно вызывает функцию в hello_dll, а затем вылетает при вызове ft2xx.dll.

(я переименовал библиотеку в ftd2xx_2.04.06, чтобы отличить guish их от других версий У меня есть. Более новые версии не работают лучше.)

Ссылка с -verbose дает:

i686-w64-mingw32-gcc -Wall -m32 -g -O2 -c -I . -o app.o app.c
i686-w64-mingw32-gcc -Wall -m32 -o app.exe app.o -Wl,-verbose -L. -lhello_dll -lftd2xx_2.04.06
GNU ld (GNU Binutils) 2.34.50.20200227
  Supported emulations:
   i386pe
using internal linker script:

<snip>

/usr/lib/gcc/i686-w64-mingw32/9.2.0/../../../../i686-w64-mingw32/bin/ld: mode i386pe
attempt to open /usr/i686-w64-mingw32/sys-root/mingw/lib/../lib/crt2.o succeeded
/usr/i686-w64-mingw32/sys-root/mingw/lib/../lib/crt2.o
attempt to open /usr/lib/gcc/i686-w64-mingw32/9.2.0/crtbegin.o succeeded
/usr/lib/gcc/i686-w64-mingw32/9.2.0/crtbegin.o
attempt to open app.o succeeded
app.o

<snip>

attempt to open ./hello_dll.lib succeeded
./hello_dll.lib
(./hello_dll.lib)d000001.o
(./hello_dll.lib)d000000.o
(./hello_dll.lib)d000002.o

<snip>

attempt to open ./ftd2xx_2.04.06.lib succeeded
./ftd2xx_2.04.06.lib
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll
(./ftd2xx_2.04.06.lib)FTD2XX.dll

:::::::::::::::: ::::::::::::

Я получил 32-битную совместимую версию gdb. Когда я запускаю gdb:

GNU gdb (GDB) 7.7.50.20140303-cvs
<snip>
This GDB was configured as "i686-pc-mingw32".
<snip>
(gdb) break main
(gdb) Breakpoint 1 at 0x40267b: file app.c, line 28.
(gdb) run
(gdb) Starting program: C:\_d\aaa\pd\src\dll\pathological\app.exe
[New Thread 1428.0x2528]

Breakpoint 1, main (argc=1, argv=0x9b2f70) at app.c:28
28              dostuff();

(gdb) info share
(gdb) From        To          Syms Read   Shared Object Library
0x774e0000  0x77644ccc  Yes (*)     C:\Windows\SysWOW64\ntdll.dll
0x753d0000  0x754cadec  Yes (*)     C:\Windows\syswow64\kernel32.dll
0x75ea1000  0x75ee6a3a  Yes (*)     C:\Windows\syswow64\KernelBase.dll
0x64081000  0x6408a1d8  Yes         C:\_d\aaa\pd\src\dll\pathological\hello_dll.dll
0x75041000  0x750eb2c4  Yes (*)     C:\Windows\syswow64\msvcrt.dll
(*): Shared library is missing debugging information.
(gdb) A debugging session is active.

(gdb) c
Continuing.
Hello dll.             <--- The function in hello_dll.dll prints this.


Program received signal SIGSEGV, Segmentation fault.
0x8000004c in ?? ()                        <----- call to FT_GetLibraryVersion()

(gdb) bt
#0  0x8000004c in ?? ()
#1  0x0040158e in dostuff () at app.c:49
#2  0x00402680 in main (argc=1, argv=0x8e2f70) at app.c:28
(gdb)

Он связывается с библиотекой без жалоб, но когда я запускаю exe, он (молча) не загружает dll.

У кого-нибудь есть идеи? Есть ли какой-то элемент управления компоновщиком, который мне не хватает? Есть ли другие c инструменты диагностики или отладки, чтобы разобраться в этом дальше?

:::::::::::::::::::::::

отредактировать 11.07.20

Я выложу код. (Если я знаю, как это сделать. Я здесь новичок.)

Это должно быть показано в «общей информации», но это не так, как вы можете видеть выше.

I ' м подозревая имя украшения. Objdump -x файла .exe показывает запись для FTD2XX.dll в таблицах импорта. Но под ним не отображается ни vma, ни связанное имя. Я подозреваю, что при загрузке программы загрузчик не видит vma / name и решает, что ему действительно не нужно загружать dll.

В .idata есть таблица импорта по адресу 0x406000

<snip>

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00006000   0000607c 00000000 00000000 00006218 0000614c

    DLL Name: FTD2XX.dll
    vma:  Hint/Ord Member-Name Bound-To
                                                      <----- empty?

 00006014   00006080 00000000 00000000 000064f8 00006150

    DLL Name: hello_dll.dll
    vma:  Hint/Ord Member-Name Bound-To
    6224        1  hello_dll

 00006028   00006088 00000000 00000000 00006554 00006158

    DLL Name: KERNEL32.dll
    vma:  Hint/Ord Member-Name Bound-To
    6230      277  DeleteCriticalSection
    6248      310  EnterCriticalSection

<snip>

::::::::::::::::::::::::::::::::::::::::::::

edit 2, 7/11/20

Это программа, которая вызывает функции в библиотеках DLL.

/* app.c

   Demonstrates using the function imported from the DLL.
*/

// 200708 pathological case. Based on the simple hello_dll.

//#include <stdlib.h>
// for sleep
#include <unistd.h>
#include <stdio.h>
// for dword
#include <windef.h>
// for lpoverlapped
#include <minwinbase.h>

#include "hello_dll.h"
// My legacy app, and really all others too, use 2.04.06.h
#include "ftd2xx_2.04.06.h"
//#include "ftd2xx_2.02.04.h"

///////////////////////////

void dostuff( void );
void call_ft_listdevices( void );

///////////////////////////

int main(int argc, char** argv)
{
    FT_STATUS status;
    DWORD libver;

    //dostuff();

    printf( "Calling hello_dll():\n" );
    fflush( stdout );
    hello_dll();
    fflush( stdout );
    printf( "Back from hello_dll()\n" );
    fflush( stdout );

    sleep( 1 );

    printf( "Calling FT_GetLibraryVersion().\n" );
    fflush( stdout );

    status = FT_GetLibraryVersion( &libver );
    if( status == FT_OK ){
        printf( "FTD2XX library version 0x%lx\n", libver );
        fflush( stdout );
    }
    else{
        printf( "Error reading FTD2XX library version.\n" );
        fflush( stdout );
    }

    // 200710 Adding call to different ft function did
    // not result in entries in the import table.
    //call_ft_listdevices( );

    return 0;
}

Я не думаю, что есть необходимость включать код для моя hello_dll. Работает.

У меня три версии FTD2XX. Я очень осторожен с отслеживанием версий. Кроме того, когда кто-то бьется головой об стену, дважды проверяйте апелляции на версии на раннем этапе, чтобы положить конец боли.

Я нашел неожиданную копию FTD2XX.dll. Он находится в c: / Windows / SysWOW64. Это самая старая из трех версий, которые у меня есть. Версии моего приложения, которые были скомпилированы до того, как возникла эта проблема, корректно работают с использованием этой dll в этом месте.

1 Ответ

0 голосов
/ 15 июля 2020

Решено.

Ошибка в 2.34.50.20200227 i686-w64-mingw32-ld.exe. Он не будет работать с ftd2xx.lib, независимо от версии ftd2xx, насколько я могу судить.

2.25.51.20150320 и 2.29.1.20171006 работают с ftd2xx.lib. Я вернулся к 2.29 mingw64-i686-binutils. Я снова бегу.

...