Нарушение доступа внутри вызова LoadLibrary () - PullRequest
1 голос
/ 02 ноября 2010

Я сталкиваюсь с нарушением доступа при вызове DLL внутри LabVIEW.Давайте назовем DLL "extcode.dll".У меня нет его кода, он исходит от внешнего производителя.

Запустив его в Windbg, он остановился с сообщением:

(724.1200): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a:

И стек вызовов:

ntdll!RtlNewSecurityObjectWithMultipleInheritance+0x12a
ntdll!MD5Final+0xedfc
ntdll!RtlFindClearBitsAndSet+0xdf4
ntdll!RtlFindClearBitsAndSet+0x3a8
ntdll!RtlFindClearBitsAndSet+0x4b9
ntdll!RtlCreateProcessParametersEx+0x829
ntdll!LdrLoadDll+0x9e
KERNELBASE!LoadLibraryExW+0x19c
KERNELBASE!LoadLibraryExA+0x51
LabVIEW!ChangeVINameWrapper+0x36f5
LabVIEW!ChangeVINameWrapper+0x3970
LabVIEW!ExtFuncDynLibWrapper+0x211

Обратите внимание, что зависимости extcode.dll загружаются до нарушения прав доступа.

Ситуация случайная, но когда это происходит, все последующие попытки приводят к ней.

Код представляет собой простую функцию LabVIEW, вызывающую функцию в DLL, и его прототип очень прост (int function(void)), поэтому он не может быть неверной конфигурацией параметров вызова или арифметики указателей.Я проверил каждую комбинацию соглашений о вызовах и уровней проверки ошибок.

DLL отлично работает при вызове в других средах (.NET и C).

Я обнаружил, что RtlFindClearBitsAndSet связан сманипуляции с битовыми массивами

О чем вы думаете?Как вы думаете, это проблема в extcode.dll, LabVIEW или Windows?

PS: я использую LabVIEW 2010 64-разрядная, в Windows 7 64-разрядная (и extcode.dll 64-разрядная).Мне не удалось воспроизвести его в 32-битной системе.

11/18 EDIT

В итоге я создал отдельный exe-файл, который оборачивает DLL;LabVIEW связывается с ним через каналы.Это работает отлично, но я все еще не понимаю, почему загрузка DLL в LabVIEW может привести к сбою.

Ответы [ 5 ]

1 голос
/ 04 марта 2011

Также будет сообщено о нарушении доступа (0xc0000005), если на вашей машине включена DEP (Предотвращение выполнения данных) и он не одобряет действия, предпринимаемые вашим двоичным файлом (EXE или DLL). DEP обычно отключено по умолчанию в Windows XP, но активно в Windows Vista / Windows 7.

DEP - это аппаратная мера безопасности, разработанная для предотвращения вредоносного кодавыполнение некоторых байтов, которые ранее считались «просто некоторыми данными»;У меня было несколько дополнений, все из которых требовали повторной компиляции поврежденных двоичных файлов с последней версией Microsoft Visual Studio;это позволяет вам установить флаг, который определяет, поддерживает ли ваш двоичный файл DEP .

Некоторые полезные ресурсы:

1 голос
/ 05 ноября 2010

Если все работает нормально при вызове из C, вы можете прекратить работу с Windbg, потому что DLL, вероятно, в порядке. Что-то не так с тем, как вызывается DLL, и как только DLL перезаписывает часть памяти LabView, все кончается, даже если может потребоваться 1000 итераций, прежде чем что-то действительно пойдет kablooey.

Сначала проверьте ваши соглашения о вызовах, C или StdCall. Соглашение о вызовах C используется по умолчанию, а StdCall - почти то, что вам нужно. (Проверьте файл заголовка DLL.) LabView 2009, очевидно, сделал некоторую автоматическую проверку и исправление соглашений о вызовах, но переход на LLVM в LV 2010 сделал это невозможным; теперь это просто танки.

Если после изменения этого значения все еще нет, проверьте ваши аргументы вызова еще раз. что вы передаете, скаляры или данные указателя? Вы не можете получить доступ к памяти, выделенной DLL из LabView, не выполняя некоторые хитрые действия, хотя вы можете выделить память (т.е. байтовый массив) в LabView и передать указатель на нее в DLL для ее изменения.

Кроме того, если вы получаете указатель (например, refnum) из более раннего вызова DLL и возвращаете его, проверьте размер указателя. Функция библиотеки вызовов LabView теперь имеет тип «целочисленный размер указателя», который генерирует тип соответствующего размера в зависимости от того, вызывается ли он в 32-битном или 64-битном LabView. (Это всегда 64 бит на проводе, потому что это должно быть определено во время компиляции.) Тот факт, что ваша DLL работает в 32, предполагает, что это возможно.

Также имейте в виду, что структуры C часто выравниваются компилятором (C). Если вы передаете указатель на структуру, состоящую из Uint8 и UInt16, компилятор C выделит для этого 32 бита (или, возможно, даже 64 бита). Вам нужно дополнить структуру (кластер) в LabView, чтобы она соответствовала, или написать DLL-оболочку для сборки структуры.

1011 * Роб *

0 голосов
/ 22 мая 2019

При работе с git и cygwin под NTFS я обнаружил, что иногда исполняемый бит не установлен (или не установлен во время извлечения или некоторых файловых операций) - внутри cygwin cd перейдите в папку и выполните

chmod a+rwx *.dll

и проверьте, если он что-то меняет (и проверьте, хотите ли вы это так!).Я нашел этот вопрос при поиске сбоя LoadLibrary () с GetLastError (), возвращающей 5 (не «0xc0000005»), и решил проблему с помощью этого вызова chmod.

0 голосов
/ 18 ноября 2010

Еще одна попытка: щелкните правой кнопкой мыши на вызове DLL, выберите «Настройка» и убедитесь, что вы работаете в потоке пользовательского интерфейса, а не в потоке. Иногда это помогает.

0 голосов
/ 08 ноября 2010

Это трудно диагностировать удаленно, но вот пара идей.

Тот факт, что ваша функция не принимает аргументов, означает, что либо функция действительно тривиальна, либо в dll имеется некоторое сохраненное состояниеэто учитывает предыдущие вызовы функций.Может быть, сбой в этой функции - только индикатор, и у вас есть проблема с предыдущим вызовом функции?Есть ли процедура инициализации, которую вы не вызываете?

Если у вас есть проблема только при использовании 64-битного labview, я думаю, что есть проблема с 64-битной версией dll, но если вы уверены, что у вас нет проблем с точнымтакие же звонки при использовании dll в других средах, я в тупике.Возможно, вы используете неверное соглашение о вызовах (stdcall или cdecl) в labview.

Вы пытались импортировать DLL и заголовок с помощью мастера импорта labview?Это может помочь избежать глупых ошибок с прототипами.

...