таблицата символ, символичното машината и стек проход
Отстраняване на грешки в програмите
Истинският умения в писането дебъгерите въз основа на характера на машината (т.е.. Д. На код, който манипулира таблицата със символи). Отстраняване на грешки в традиционен език ниво сглобяване интересно за първите няколко минути на работа, но бързо се отегчават. таблицата със символи (символ таблици), известен също като символи за отстраняване на грешки (дебъгване на символи) - това е, което прави номера шестнадесетични да струни, имената на функциите и имената на променливите на изходни файлове. маси от символи съдържат допълнителна информация за видовете, които програмата ви използва. Тази информация позволява дебъгер да се появи на "сурови" данни като структури и променливи, които дефинирате в програмата си. За да се справят със съвременните символи масите е трудно, защото най-често използваният формат тях - PDB (база данни програма - програма база данни), не е документирана, и притежателите на права не планират да го документира. За щастие, можете да получите най-малко частичен достъп до таблицата със символи.
Формат за отстраняване на грешки символа
Преди да навлезем в обсъждането на организацията на достъп до таблицата със символи, ние даде обща представа за различните символи формати за отстраняване на грешки. Мисля, че дори и опитни програмисти разбират лошо в тези формати, така че нека да поговорим за това по-подробно.
SYM - най-старият формат, който се използва в дните на MS-DOS и 16-битова версия на Windows. В момента SYM-формат се използва само за отстраняване на грешки символи в Windows 98. SYM-формат се използва само, защото голяма част от ядрото на операционната система ядрото все още е 16-битов код. Единственият дебъгер активно използване на героите на този формат - това WDEB386.
COFF (Постигането на общата цел формат на файла - общ обект файлов формат): декан на първата таблица формат характер, който беше въведен в Windows NT 3.1 (първата версия на Windows NT). Екип на Windows NT разработчиците от своя опит в разработването на операционната система и искате да се зареждат Windows NT с помощта на някои от съществуващите инструменти. COFF формат и е част от по-голям спецификация, която се използва от различни доставчици на UNIX-базирани системи, опитвайки се да се установят общи формати на бинарни файлове. Въпреки WINNT.H е пълна спецификация COFF-символи, инструменти на Microsoft генерират само някои от най-ее - с обществеността, функции и глобални променливи. В Microsoft използва за поддържане на източника и онлайн информация, но постепенно се отдалечи от формата COFF в полза на по-модерни формати символ таблици.
Формат C7 или CodeView появи в дните на MS-DOS, като част от системата на Microsoft C / C ++ програмиране версия 7. Може да сте чували името "CodeView". Това е името на стария Microsoft дебъгер. C7 формат е модифициран за поддържане на операционната система Win32 и черно яребици може да генерира този формат, като се започне CL.EXE компилатор от командния ред с ключа / Z7 или като изберете елемента от падащия списък C7 Compatible1 Debug Информация за C / C ++ диалоговата кутия ProjectSettings.
Тук и по-долу, ние говорим за интерфейса с IDE Microsoft Visul C ++. - Per
Ако е необходимо, разбира се, можете да използвате формата S7. но е по-добре да не го прави. Откажи се от всичко е необходимо използването на формата C7 по две причини. Първо, тя се изключва автоматично постепенно оформление, поради което значително увеличава времето връзка. От друга страна, значително увеличи размера на изпълними файлове. Можете да премахнете символично информация чрез програма REBASE.EXE. но има и формати (например ППБ), които го премахнете автоматично.
PDB - най-често в употреба днес са символни формати, поддържа и двата Visual C ++ и Visual Basic. За разлика от формата, C7, PDB-код се съхранява в отделен файл или файлове, в зависимост от това как е подредена на заявлението. По подразбиране, зареждане на файлове Visual C ++ 6 е свързан с ключ / PDBTYPE: Септември което поставя информация за видовете в VC60.PDB файл, и самите герои - в даден файл <имя-двоичного-файла>.DOM. Отдел на информация за вида на отстраняване на грешки символи ускорява конфигурация и изисква по-малко дисково пространство. Въпреки това, документацията се посочва, че ако се построи двоичен файл, който може да трасира й другите, че цялата информация за видовете и символи за отстраняване на грешки са консолидирани в единна PDB-файл, трябва да укажете ключ / PDBTYPE: CON. За щастие, Visual Basic автоматично използва тази опция.
Ако сте заинтересувани от символичен машина и да започне да проучи възможностите за програмиране, рано или късно ще се срещнете с героите от друг тип - омар. Символи от този тип се появяват само в някои приложения на Microsoft. Те могат да бъдат намерени в понякога получаване на информация характер сметище използване DUMPBIN.EXE полезност. задейства с параметрите / символи. (DUMPBIN.EXE разпространяван с Visual C ++ програмната система.) А характер Омар формат напълно без документи. Както вече бе споменато по-рано, Microsoft използва специален инструмент за вътрешно преустройство, че на прекомпилирани файл, за да вкара най-често причинена от код в началото на файла. Омар -Symbols имат някаква връзка с символи за отстраняване на грешки, които вземат под внимание тази стъпка poslekomponovochny.
Такава се извършва оптимизация и програмата работна Set тунер (WST), предоставен с SDK на платформата. WST работи на функционално ниво, без да прониква в функции, като Microsoft инструмент се понижава до нивото на така наречените базови единици. Следният код фрагмент на блоковия елемент е показан със стрелки:
ако (ИСТИНСКИ = blsError)
> <- Конец базового блока.
Достъпът до информация за характера
В WDBG проста обвивка клас (C ++ език) се използва, който е показан (SYMBOLENGINE.H) файл в Обява 4-7. Първоначално този клас е написан като част от BUGSLAYERUTIL.DLL библиотека. Това значително съкратена версия на API символичен DBGHELP.DLL машина. но то има някои допълнителни функции, за да отговори на предизвикателствата, пред които са изправени по-стари версии на IMAGEHLP.DLL символични машини. SYMBOLENGINE.H изходния код е показан в случай че трябва да използвате този клас със старите символи машини аз MAGEHLP.DLL.
Listng4-7 .Fayl SYMBOLENGINE.H
"дебъг" (Microsoft Press)
Този клас - съкратена версия на характера DBGHELP.DLL машина. CNN обхваща само тези функции, които имат уникална стойност ДРЪЖКАТА-ЕВРОВОК. Другите функции на DBGHELP.DLL на машината характер са глобални, така че те не са включени в този клас.
При определянето на тази постоянна клас няма да работи с грешка SymGetLineFromAddr, когато търсят PDB fMile се провали след първата търсенето.
При определянето на тази константа, този клас ще използва друг метод на инициализиране характер машина - BSUSymlnitialize на BUGSLAYERUTIL.DLL. Освен това, в процеса на снимане кутия ще започне да работи за всички 32-битови издания на Windows системи. При използване на тази дефиниция, освен SYMBOLENGINE.N трябва да включва също така BUGSLAYERUTIL.H файл.
// Можете да активирате или IMAGEHLP.DLL или DBGHELP.DLL.
// Включване на тези директиви, в случай, че потребителят не забравя
// за оформлението на съответните библиотеки
#pragma коментар (Иб "dbghelp. ИЪ")
#pragma коментар (Иб "версия, либералните")
// Голямата идеята за създаване на класове на обвивки на структури, които
// имат триизмерна област, дойде от колега журналист от MSJ Fields
// (Paul DiLascia). Благодаря ви, Пол!;
// Аз не включи в клас постоянно IMAGEHLP_SYMBOL, защото тя
// структура променлив размер.
структура CImageHlp_Module. обществен IMAGEHLP_MODULE
memset (тази, NULL, sizeof (IMAGEHLP_MODULE));
SizeOfStruct = sizeof (IMAGEHLP_MODULE);
структура CImageHlp_Line. обществен IMAGEHLP_LINE
memset (тази, NULL, sizeof (IMAGEHLP_LINE));
SizeOfStruct = sizeof (IMAGEHLP_LINE);
// характер класа на CSymbolEngine машинния клас
Публично-конструктор и деструктор
// За да използвате този клас, обадете се на метода за Symlnitialize
// инициализиране на характера на машината и след това да използвате други методи
// вместо съответните роли на DBGHELP.DLL
виртуален -CSymbolEngine (свободен)
Допълнително информация публично-функция
// Връща версия използва DBGHELP.DLL файла.
// За да се превърне върнатите стойности в четим формат,
// параметър szVer ще съдържа линия като: 5.00.1878.1
BOOL GetlmageHlpVersion (DWORD dwMS, DWORD dwLS)
възвръщаемост (GetlnMemoryFileVersion (_T ( "DBGHELP.DLL"),
BOOL GetDbgHelpVersion (DWORD dwMS, DWORD dwLS)
възвръщаемост (GetlnMemoryFileVersion (__T ( "DBGHELP.DLL"),
// Връща версия на DLL-файла четене PDB.
BOOL GetPDBReaderVersion (DWORD dwMS, DWORD dwLS)
// първо проверява MSDBI.DLL файл.
ако (TRUE == GetlnMemoryFileVersion (_T ( "MSDBI.DLL"),
иначе, ако. (TRUE == GetlnMemoryFileVersion (_T ( "MSPDB60.DLL"),
// Сега беше ред провери MSPDB50.DLL.
се върне (GetlnMemoryFileVersion (_T ( "MSPDB50.DLL"),
// Работа функция използва предходните две функции.
BOOL GetlnMemoryFileVersion (LPCTSTR szFile,
HMODULE hlnstlH = GetModuleHandle (szFile);
// Получаване на пълното име на файла изтеглената версия на
TCHAR SZ mageHlp [MAX_PATH] !;
GetModuleFileName (hlnst-Ш, szImageHlp, MAX_PATH);
// Получаване на размера на информацията за версията.
dwVerSize = GetFileVersionlnfoSize (szImageHlp.
ако (0 == dwVerSize)
// Получаване на размера на информация за версията, а сега преминаваме
LPVOID IpData = (LPVOID) нов TCHAR [dwVerSize];
ако (FALSE == GetFileVersionlnfo (szImageHlp.
dwVerlnfoHandle. dwVerSize. IpData))
изтриване [] IpData; връщане (невярно);
// уникална стойност, която ще се използва за тази
// например от символни машини. Тази стойност не трябва да бъде
// стойността на самия производствен процес, а просто - уникална стойност.
Инсталиране DBGHELP.DLL - само част от историята, защото, за да се зареди символните файлове, трябва да се гарантира тяхната наличност за характера на машината. В случай на символичната машината DBGHELP.DLL DBG-файл ще ги търсим в следните места:
- текущата работна директория, използвайте DBGHELP.DLL (не по-лоши дебъгер!);
- променлива _NT_SYMBOL_PATH среда;
- променлива _NT_ALT_SYMBOL_PATH среда;
- Променлива SYSTEMROOT среда.
Каталози, които показват системни променливи, трябва да бъдат организирани по определен начин. Например, ако прилагането състои от EXE и DLL двойка. намиращ се в директорията C: \ MyFiles, а след това по тази директория, в които трябва да се създаде следната структурата на поддиректория:
- C: \ MyFiles
- C: \ MyFiles \ Символи
- C: \ MyFiles \ символи \ Exe
- C: \ MyFiles \ символи \ Dll
Две скорошни поддиректория са предназначени за настаняване на съответния кандидатстване DBG-файлове.
Единствената разлика при работа с ППБ-файлове е, че герой ще търси кола DBGHELP.DLL PDB -files в основната директория заявление и да се опита да се зареди ППБ от тази директория. Ако характер DBGHELP.DLL машината няма да бъде в състояние да изтеглите ППБ-файлове от нея, тя ще се опита да търси и да ги изтеглите точно толкова DBG-файлове (т.е.. Д. от същото поддиректории, които трябваше да бъдат създадени за съхранение на отстраняване на грешки файлове знака).
Това означава, че за всеки тип кандидатстване за работа файлове, отделна поддиректория за DBG-файлове. - Ed.
Къде се съхранява като двоични файлове на приложението и съответните ППБ-файлове, които са били създадени от свръзката на етапа на отстраняване на грешки изгражда. - Ed.
За щастие на всички нас, няма нужда да пишете по поръчка код, за да премине на комина. В DBGHELP.DLL взе специална API функция stackwalk. която се грижи за цялата работа с комин. WDBG го използва по същия начин, както прави C ++ дебъгер визуалната. Единственият проблем - няма подробна документация STACKFRAME структура. Обява 4-8 покажа само тези области на тази структура, която трябва да се попълни. stackwalk функция толкова добре се погрижили за всички детайли, които може да не знаете, че оптимизиран код в прохода на стека може да бъде доста трудна задача. Причината за тези трудности се крие във факта, че за някои функции на компилатора да извършите оптимизиране далеч от зоната на комин, т.е.. Е. От мястото, където избута от нейните елементи. Съставители Visual C ++ и Visual Basic доста агресивен, когато те изпълняват оптимизация, и ако те могат да използват регистър стека като работник, а след това те ще го направя. За да се улесни работата с купа в такива ситуации, компилаторът генерира, което се нарича FPO данни (Frame Pointer Пропускане). FPO-данни - таблица, която stackwalk функция се използва, за да се изчисли, свързани с обработката на тези функции, които липсват на нормалната зона на купа. Ние считаме, FPO-данни и защото препратки към тях се срещат понякога в MSDN и различни дебъгерите. Възможно е да се научите повече за структурата на файла с данни FPO-WINNT.H.
Обявата 4-8. InitializeStackFrameWithGontext на i386CPUHELP.C
BOOL CPUHELP_DLLINTERFACE _stdcall
InitializeStackFrameWithContext (STACKFRAME * pStack,
ASSERT (FALSE == IsBadReadPtr (pCtx, sizeof (КОНТЕКСТ)));
ASSERT (FALSE == IsBadWritePtr (pStack, sizeof (STACKFRAME))
ако ((TRUE == IsBadReadPtr (pCtx, sizeof (контекст))) ||
(Вярно == IsBadWritePtr (pStack, sizeof (STACKFRAME))))