Отладка приложений

Общие проблемы реализации


Разобравшись с подключением экспорта по порядковым значениям, я больше не сталкивался со сколько-нибудь серьезными проблемами при реализации LIMODS в целом. Одно интересное свойство, реализованное в LIMODS.EXE, — это автоматическая отметка элементов управления видом дерева (см. рис. 14.1). Если установить или снять отметку корневого узла в представлении дерева (имя модуля), автоматически выполняется установка (или снятие) отметок всех дочерних узлов (исходных файлов). Для выполнения подобной работы нужно было организовать уведомление о переключении метки. Все это реализовано в файле LIMODSVIEW.CPP, который можно найти на сопровождающем компакт-диске.

Самая большая проблема, возникшая при реализации LIMODS, была связана с библиотекой стандартных шаблонов (STL). Я допускаю, что разработчики STL умнее меня, но, тем не менее, я не ожидал что, Visual С++-код STL окажется настолько непроницаемым. Одна расшифровка ошибок компиляции заняла очень много времени. Кроме того, было чрезвычайно сложно разобраться, в какой части кода произошел отказ, или как что-то в нем работает. В соответствии с рекомендациями главы 2, я использовал предупреждения компилятора 4-го уровня и рассматривал все предупреждения как ошибки, и при компиляции кода STL был завален предупреждениями С4786 ("'identifier': identifier was truncated to '255' characters in the debug information" — '"идентификатор1: в отладочной информации был усечен до '255' символов") для любого класса из шаблонов STL, который имеет более двух символов в своем имени.

Секрет предупреждений С4786 состоит в том, что отключать их надо через директиву #pragma warning перед включением любых файлов заголовков STL. Кроме того, методика, использующая директиву #pragma warning, работает лучше, если в главный предварительно компилированный заголовочный файл включить только STL-заголовки, а обычные предупреждения в предварительно компилированном заголовке отключите раз и навсегда. Хотя при этом и пришлось немного повозиться, но все же удалось сэкономить время, используя STL вместо реализации своих собственных возрастающих массивов и классов отображений (map classes).


Что касается последней проблемы, с которой я столкнулся, то не могу сказать, была ли это ошибка в компиляторе или недопонимание с моей стороны. В LIMODSDLL.DLL применяется статический массив HOOKFUNCDESC, содержащий указатели реальных функций для DiagOutputA и DiagOutputw из BUGSLAYERUTIL.DLL. В функциях подключения используется указатель реальной функции вне структуры как пункт назначения для оператора перехода. Проблема заключалась в том, что ссылка на второй элемент в массиве создавала недействительную ссылку. Исходная строка встроенного ассемблера

JMP g_stBugslayerUtilRealFuncs [0] .рРгос



генерировала строку кода языка ассемблера

JMP g_stBugslayerUtilRealFuncs+4h

которая была правильной. Однако исходная строка, которая сослалась на второй элемент в структуре:

JMP g_stBugslayerUtilRealFuncs[l].pProc

генерировала

JMP g_stBugslayerUtilRealFuncs+5h,

тогда как я думал, что она должна генерировать

JMP g_stBugslayerUtilRealFuncs+OCh

Следовательно, генерированный код выполнял переход в "ничейную" область памяти. Я пытался разрешить эту проблему, используя в качестве ссылки оператор

JMP g_stBugslayerUtilRealFuncs[0x8].рРгос

Это частная проблема, и она может возникнуть, только если разработчик добавит к LIMODSDLL.DLL собственные специальные функции трассировки. Добавляя такие функции, используйте в качестве примеров таблицы из BUGSLAYERUTIL.DLL.



Содержание раздела