Как отладить плоский преобразователи

Переводы статьи Переводы статьи
Код статьи: 133722
Развернуть все | Свернуть все

В этой статье

Аннотация

Отладка плоский преобразователи, создаваемого компилятором преобразователь может оказаться трудной задачей Поскольку преобразователь механизмом является сложным и отладки инструменты, способное Трассировка через преобразователи трудно использовать. В статье представлены общей стратегии для отладки плоский преобразователями, несколько конкретных отладки приемы и руководство по поиску неисправностей, объясняется, как устранить многие Общие проблемы преобразования.

Дополнительная информация

Ограничения на действия целевой библиотеки DLL

Перед тем как начать отладку преобразователи, имейте в виду, что существуют некоторые ограничения в целевой библиотеке DLL можно сделать внутри преобразователь. Это происходит потому, что На базе Win16 приложение, вызывающее DLL на основе Win32 не на базе Win32 процесс; Аналогичным образом является вызов библиотеки DLL на основе Win16 приложения на основе Win32 не на базе Win16 процесса. Включать общие особые ограничения:

  • Нельзя создавать потоки внутри преобразователь из приложения на базе Win16 на основе Win32 DLL.
  • Код внутри на базе Win32 DLL, вызываемых преобразователи должна требовать немного стекового пространства, так как на базе Win16 предает стеки гораздо меньше, чем приложения на основе Win32.
  • На базе Win16 библиотеки DLL, содержащие процедуры обслуживания прерываний (ISRs) не должен thunk на основе Win32 DLL при обработке прерываний.
  • Win32-приложения не должен передавать указатели на данные, расположенные в стеке как параметры преобразователи или на базе Win16 библиотеки DLL, переключения стеков вызова.

Почему отладки плоский преобразователи могут возникнуть трудности

Отладка плоский преобразователи сложно, частично потому, что обычное thunk механизм является сложной частью ядра Windows. Его сложность проистекают из факта ее следует расположить вызовы функций в 32-разрядных скомпилированный код в вызовы совместим с 16-разрядного кода и наоборот. Поскольку используется 32-разрядный код различные типы данных и ЦП зарегистрировать наборы из 16-разрядный код, плоский преобразователь механизм должен преобразовать параметры функции переключения стеков и перевод возвращаемые значения. Он оптимизирован по скорости, еще должен быть разрешен с приоритетным прерыванием Win32 код вызова кода режиме без вытеснения Win16. Выполняется создание компилятором преобразователь плоский преобразователи значительно проще, чем вручную создавать их, но он не гарантирует полную надежность.

Отладка плоский преобразователи сложно не только потому, что сам механизм является сложные, но также потому, что необходимые средства отладки, тем сложнее Образец. Отладчики на уровне приложения, такие как Microsoft Visual C++ отладчик и WinDBG нельзя трассировки через преобразователи, так как они состоят из 16-разрядные и 32-разрядный код и заставляет систему для утверждения или выпуск Win16Mutex. Для трассировки через преобразователь можно с помощью системного уровня отладчик, такие как WDEB386.EXE-ФАЙЛА. Основные недостатки с помощью WDEB386.EXE необходимо знать язык ассемблера Intel x 86, знать, как корпорация Intel x 86 микропроцессоры работать и запомнить большинство команд отладчика.

Лучшая стратегия для использования

Лучшая стратегия для отладки преобразователи — чтобы разделяй и властвуй, так как достаточно просто и позволяет устранить большинство проблем, при необходимости трассировка кода в отладчике системного уровня. Обычное Преобразователи состоят из библиотеки DLL на основе Win32 и библиотеки DLL на основе Win16, поэтому Возможно, чтобы проверить каждый из них отдельно перед проверкой их вместе. Создание приложения на базе Win16 для тестирования на базе Win16 DLL и создания Приложения на основе Win32 для тестирования на базе Win32 DLL. Это позволяет проверить работу каждой стороны с помощью разнообразных средств отладки правильно.

Контрольный список предварительных - до компиляции с параметром компилятора преобразователь

После подтверждения правильности работы каждой стороны пора поместить два вместе, чтобы проверить преобразователь сам. Прежде чем компилировать преобразователь с Компилятор преобразователь сделать предварительно проверить следующие элементы:
  1. В сценарии преобразователь убедитесь, что каждая функция имеет правильное количество и типы параметров. Убедитесь, что компилятором преобразователь поддерживаются типы параметров. В противном случае будет необходимо каким-либо образом изменить параметр для передачи данных с помощью поддерживаемого типа.
  2. Если передать любой структуры в качестве параметров убедитесь, что использовать ту же структуру отборочных на базе Win32 DLL, на базе Win16 DLL и преобразователь кода сценария. Задайте упаковкой структуры в C/C++ компилятора командной строки, а в командную строку компилятора преобразователь. Обратите внимание, что переключатель компилятора преобразователь упаковки нижнего регистра для 16-разрядных стороны и верхнего регистра, для 32-разрядных стороны.
  3. Убедитесь в функции, преобразование к корректно экспортированы и использование языка PASCAL, вызов соглашение, если они являются 16-разрядных или указывая, если они являются 32-разрядное. Преобразователь кода компилятор не поддерживает слова _cdecl и соглашения о вызове __fastcall.
  4. Убедитесь в том, на основе Win32 DLL вызывает ThunkConnect32() при каждом вызове функции его DllMain(). Аналогичным образом Убедитесь, что библиотеки DLL на основе Win16 экспортированную функцию DllEntryPoint(), отдельно от его LibMain(), вызывает ThunkConnect16() и возвращает значение TRUE, если ThunkConnect16() завершается успешно.

    ПРИМЕЧАНИЕ: Вы фактически вызов XXX_ThunkConnect16() и XXX_ThunkConnect32() где XXX — это символ определяется с помощью параметра -t компилятор преобразователь. Код, созданный компилятором преобразователь эти символы используются для создания таблиц, которые вызывают ThunkConnect16() и ThunkConnect32.
  5. Убедитесь, что значение, указанное в параметр -t командной строки компилятора преобразователь одинакова для Win32 и библиотеки DLL преобразователь Win16. Значение должно соответствовать также префикс ThunkConnect вызовы в на основе Win16 и Win32 DLL (см. Примечание на шаге 4).
  6. Убедитесь, что библиотека DLL на базе Win16 DLLEntryPoint экспортированы с помощью ключевого слова RESIDENTNAME в своем определении модуля (.Файл DEF). Без ключевого слова RESIDENTNAME ThunkConnect32 и ThunkConnect16 вызов завершится ошибкой и не загружает библиотеки DLL.
  7. Убедитесь, что 16-разрядные библиотеки DLL XXX_ThunkData16, экспортированные с помощью ключевого слова RESIDENTNAME в своем определении модуля (.Файл DEF).
  8. Проверьте на базе Win16 DLL файла makefile, компилятор ресурсов является Пометка DLL 4.0. Если он помечен как меньше, чем 4.0, он не будет загружать и преобразователь не удастся.
  9. Функция-преобразователь 32 бит на 16-разрядных возвращает указатель, убедитесь, что базовый тип является один и тот же размер 16-разрядные и 32-разрядные сторонах преобразователь. Если другой размер базового типа преобразователя компилятор выдает сообщение о том, «Не возвращают указатели неидентичных типов». Возвращает указатель на тип данных другого, но совместимый, является одним из способов решения этой проблемы. Например преобразователь не может возвращать указатель int, так как int два байта со стороны 16 бит, но четыре байта со стороны 32-разрядных. Измените тип возвращаемого преобразователь указатель на int в указатель типа long в сценарий преобразователь и исходный код библиотеки DLL Win16 на основе Win32 и.

    Если написать преобразователь 16-разрядного в 32-разрядный, возвращает указатель на преобразователь компилятор выдает сообщение об ошибке, «типы указателей не может быть возвращена.» Преобразователь кода компилятор не допускает преобразователи 16-разрядного в 32-разрядный указатель типами возвращаемых значений из-за после преобразователь возвращает из 32-разрядных функций, указатель будет не данных в адресном пространстве правильный процессов на основе Win32. Это обусловлено тем, что адресные пространства всех процессов на основе Win32 с помощью того же диапазона адресов и заблаговременно переключения контекста.
  10. Если компоновщик сообщает об ошибке «неразрешенных внешних» и символ — это имя функции, которое является одинаковым во весь исходный код, файлы определения модуля и преобразователь кода сценария, убедитесь что все вхождения этого прототипа. Со стороны Win32 функции преобразователь должен быть объявлен с типом __stdcall; со стороны Win16 функции должен быть объявлен с типом языка PASCAL. В проектах C++ необходимо объявлять и определять функции преобразователь с обеих сторон с спецификатор компоновки extern «C» для типа языка PASCAL или __stdcall.

Руководство по trouble-Shooting - после компиляции с параметром компилятора преобразователь

После проверки начальные сведения построение библиотеки DLL на преобразователь и запустите их. Если при выполнении продолжения дальнейшего тестирования, чтобы убедиться, что они все рок сплошной. Если они не выполняются, используйте следующее руководство по устранению неполадок определить и устранить причину проблемы.

ThunkConnect16() в Win16 или ThunkConnect32() в сторону Win32 не выполняется:

  1. Запуск отладки версий системных библиотек DLL. Отладочной версии KERNEL32.DLL и KRNL386.EXE содержит многие диагностические сообщения о том, почему не удалось инициализировать преобразователь. Для выполнения отладки версий системных библиотек DLL, воспользуйтесь значком «Коммутатор для библиотеки отладки» в меню Пуск, в меню Сервис Win32 SDK. «Ключ без отладки библиотек DLL» для переключения обратно в версию.
  2. Убедитесь, что библиотека DLL на базе Win16 должен вызывать ThunkConnect16() и на базе Win32 DLL имеет соответствующий вызов ThunkConnect32(). Если отсутствует один из них, затем второй произойдет сбой и преобразователь библиотеки DLL не удастся загрузить.
  3. Разместить точки останова в библиотеке DLL Win32 DllMain() и DllEntryPoint() и LibMain() Win16 DLL функции, чтобы увидеть, какие библиотеки DLL не загружается.
Если вызовы ThunkConnect16() и ThunkConnect32() работают нормально, преобразователь, но по-прежнему не, пришло время для упрощения вашей преобразователь. Вы можете Фактически атаки двумя способами. Во-первых запуск, удаляя параметры из преобразователь один за другим и перекомпилировав его. Во-вторых, создать простой преобразователь который работает и построить его вплоть до сбоя, выполните следующие действия:
  1. Создание простой преобразователь и выполнять его так же, чтобы убедиться, что имеется механизм преобразователь, установлены правильно. Хорошо подходит для простых преобразователь представляет собой функцию без параметров и не возвращает значение. Если даже простой преобразователь не работает, запустите через предварительное выше, убедитесь, что установлены правильно вещи контрольный список. Перейдите к шагу 2.
  2. Убедитесь, что целевой библиотеки DLL и полагается на DLL могут быть найдены и загружены. Если она отсутствует или не удается найти загрузчик, преобразователь не будет работать.
  3. Убедитесь, что целевой библиотеки DLL не делать то, что этого не в контексте преобразователь.
Создав упрощенное преобразователь, который работает, но по-прежнему реальной преобразователь не работает, выполните следующие действия:
  1. Добавьте параметры простой преобразователь один во время определения, если параметр является причиной неполадки. Если один, убедитесь, что задан правильный тип, функция объявлена и с одинаковым номером и параметры в обе библиотеки DLL и компилятора преобразователь типов и функция объявлена как PASCAL или указывая.
  2. Если целевой DLL является библиотекой DLL, на базе Win16 и не может обращаться к его глобальных и статических данных, убедитесь, что функция экспортированного правильно. Если при использовании /GD с Visual C++, необходимо объявить и определить функцию с помощью ключевого слова __export в исходном коде DLL на базе Win16. Только со списком имя функции в определении модуля DLL (.Файл DEF) не достаточно, поскольку компилятор не выполняет.DEF-файла, поэтому он не будет генерировать код пролога и эпилога, экспортированные функции требуют.
  3. Если вызовы LocalAlloc() в свой целевой библиотеки DLL на основе Win16 причину сбоях общей защиты (GP), убедитесь, что функция экспортируется как описано в шаге 2.
  4. Если получить общий сбой в KERNEL32 просто после целевого на базе Win16 функция возвращает значение, убедитесь, что целевой функции объявлены и определены как PASCAL. C соглашение о вызовах не допускается. Хотя нехарактерны для кода c или C++, но более вероятно, на языке ассемблера, убедитесь, что целевой функции не изменять регистры DS, SS, BP, SI или DI.
  5. Если сразу после на основе Win32 целевой функция возвращает общий сбой в преобразователь адресов 32-разрядные библиотеки DLL или KERNEL32, убедитесь в том, что целевой функции объявлены указывая и что он не изменяет регистры DS, ES, FS, SS, EBP, ebx потенциально может ДАВАТЬ ESI или EDI. Код на c или C++ не должна вызывать регистрах, изменять, но ассемблерный код следует тщательно проверить.
  6. Если на вашей базе Win16 возвращает целевой функции в недопустимом месте, убедитесь, что он объявляется и определяется как ДАЛЬНЕГО. Это особенно важно для малых модель DLL; функции в DLL модели средних и крупных FAR, по умолчанию.
  7. Если произошел общий сбой в функции на базе Win16 при доступе к более 64 КБ данных из указателя, переданного в качестве параметра (то есть, указатель thunked), необходимо выделить массивы мозаичные селекторов, как описано в следующей статье Microsoft Knowledge Base:
    132005 DOCERR: Неполная документация по AllocSelector & FreeSelector
    Со стороны Win16 thunked указатели всегда состоят из одного селектора с пределом 64 КБ, что означает, что их нельзя использовать как огромный указатели. Весь исходный диапазон данных, в котором указатель доступен на базе Win16 целевой DLL - но только если создает массив мозаичные селекторы для ссылки на него и использует огромный указатель переменных для доступа к данным.
  8. Убедитесь, что используются только thunked указатель в контексте преобразователь. Селекторы, выделенной с помощью компилятора преобразователь для использования с целевых объектов на базе Win16 освобождаются сразу же Возвращает преобразователь.
  9. Разместить точки останова в начале вашей целевой функции убедитесь, что вы получите в них. Если, и отлажены целевой части независимо преобразователь причина ошибки внутри целевой объект, затем скорей цели — это делать то, что не может быть выполнена в преобразователь или ссылки на память, которая не существует. Пожалуйста, ознакомьтесь с шаги 7 и 8.

Свойства

Код статьи: 133722 - Последний отзыв: 2 июня 2011 г. - Revision: 4.0
Ключевые слова: 
kbhowto kbkernbase kbprogramming kbmt KB133722 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:133722

Отправить отзыв

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com