szimbólum táblázat, a szimbolikus gép és a verem áthaladását

programok hibakeresése

Az igazi készség írásban debuggers alapján a karakter a gép (pl. E. A kód, amely manipulálja a szimbólum táblázatot). Hibakeresés hagyományos szintű assembly nyelven érdekes az első pár perces munka, de hamar unatkozni. szimbólumtáblát (szimbólum táblázatok), más néven a hibakeresési szimbólumok (hibakeresés jelek) - ez az, ami a hexadecimális számok szöveggé, függvény nevét és a változó nevét forrás fájlokat. Karaktertáblák tartalmazhat további információt a fajta, hogy a program által használt. Ez az információ lehetővé teszi, hogy a hibakereső megjelenik a „nyers” adatok struktúrák és változók, amit meg a programban. Foglalkozni a modern szimbólum táblázatok nehéz, mert a leggyakrabban használt méret őket - PDB (Program adatbázisa - adatbázis-program) nem dokumentálták, és a jogtulajdonosok nem tervezi, hogy dokumentáljuk. Szerencsére, akkor kap legalább részleges hozzáférést biztosított a szimbólum táblát.

Format hibakeresési szimbólumok

Mielőtt belemennénk a vita a szervezet hozzáférést biztosít a szimbólum táblát, áttekintjük a különböző formátumú hibakeresés szimbólumok. Azt hiszem, hogy még a gyakorlott programozók megérteni rosszul ilyen formátumú, ezért beszéljünk erről részletesebben.

SYM - a legrégebbi formátumot használták a napon MS-DOS és 16 bites Windows. Jelenleg SYM-formátumot használjuk csak hibakeresési szimbólumokat a Windows 98 SYM-formátumot használnak csak azért, mert a nagy része a központi operációs rendszer kernel még mindig 16 bites kódot. Az egyetlen hibakereső aktívan használja a karakterek ebben a formátumban - ez WDEB386.

COFF (Common Object File Format - közös objektum formátum): Dean az első formátum karakter tábla, amelyet azért vezettek be a Windows NT 3.1 (az első változat Windows NT). Csapat Windows NT fejlesztők már tapasztalattal fejlesztése az operációs rendszer és a betölteni kívánt Windows NT segítségével néhány a meglévő eszközökkel. COFF formátum része egy nagyobb leírás, melyet a különböző szolgáltatók UNIX-alapú rendszerek, próbál létrehozni közös formátumok bináris fájlokat. Bár WINNT.H teljes leírás COFF-karakter, a Microsoft eszközök generál csak néhány ee - állami funkciók és globális változók. A Microsoft fenntartására használják forrás és online információs, de fokozatosan eltávolodott a COFF méret mellett egy modernebb formában szimbólum táblázatokat.

Format C7 vagy CodeView meg a napokban az MS-DOS részeként a rendszer a Microsoft C / C ++ programozási változat 7. Ön is hallott már a neve „CodeView”. Ez a név a régi Microsoft debugger. C7 méret módosításra került, hogy támogassa a Win32 operációs rendszer, és a nyírfajd generálhat ezt a formátumot, kezdve CL.EXE fordítóprogram a parancssorból a kulcs / Z7 vagy adja meg a elemet a legördülő C7 Compatible1 lista Debug Info a C / C ++ fül párbeszédablak ProjectSettings.

Itt és az alábbiakban beszélünk a felület IDE Microsoft Visul C ++. - Per

Ha szükséges, természetesen használhatja az S7 formátumban. de jobb nem megtenni. Lemondanak a használata a C7 formátum két okból szükséges. Először is, akkor automatikusan kikapcsol inkrementális elrendezés, ami miatt jelentősen növeli a kapcsolat ideje. Másodszor, jelentősen növelte a méretét binárisok. Akkor távolítsa el a szimbolikus keresztül információt REBASE.EXE programot. de vannak formátumok (pl EKT), melyek csökkentik automatikusan.

PDB - a leggyakoribb a manapság használt karakter formátumokat egyaránt támogatja a Visual C ++ és Visual Basic. Ellentétben a C7 méret, PDB-kód van tárolva egy külön fájlt vagy fájlokat, attól függően, hogy az alkalmazás van elrendezve. Alapértelmezésben az indító fájl Visual C ++ 6 kapcsolódik a kulcs / PDBTYPE: szeptember amely hozza információt a típusok in VC60.PDB fájlt, és a karakterek maguk - egy fájlba <имя-двоичного-файла>.DOM. Tanszék információk a fajta hibakereső szimbólumokkal felgyorsítja konfiguráció, és kevesebb lemezterületet. Azonban a dokumentáció kimondja, hogy ha építeni egy bináris fájl, amely a hibakeresés j mások, hogy minden információt a típusok és a hibakeresési szimbólumok konszolidálásra került egyetlen PDB-fájlt, akkor meg kell adni a kulcsot / PDBTYPE: CON. Szerencsére, a Visual Basic automatikusan használja ezt az opciót.

Ha érdekel a szimbolikus gép és elkezd felfedezni a lehetőségeket a programozási, előbb vagy utóbb találkozni fog a karakter egy másik típus - homár. Szimbólumok Az ilyen típusú jelennek meg csak néhány Microsoft alkalmazásokhoz. Ezek néha a megszerzése jellegű információk billenő használatával DUMPBIN.EXE segédprogramot. váltott paraméterrel / szimbólumok. (DUMPBIN.EXE terjesztett Visual C ++ programozási rendszer.) A karakter OMÁR méret teljesen dokumentált. Mint már korábban említettük, a Microsoft egy speciális belső eszköz, amely átszervezi a lefordított bináris fájlt, hogy a leggyakrabban a kód okozza a fájl elején. OMÁR -symbols van némi kapcsolat a hibakereső szimbólumokat, amelyek figyelembe veszik ezt poslekomponovochny lépést.

Az ilyen optimalizálást és a program Working Set Tuner (WST), a mellékelt Platform SDK. WST működik a funkcionális szinten, anélkül, hogy behatol a funkciókat, míg a Microsoft eszköz csökken arra a szintre, az ún alapegységek. A következő kód fragmenst az alapegység nyilakkal:

ha (IGAZ = blsError)

> <- Конец базового блока.

Hozzáférés a karakter információ

A WDBG egyszerű burkoló osztály (C ++ nyelven) használtunk, amely látható (SYMBOLENGINE.H) fájlt jegyzék 4-7. Kezdetben ez az osztály volt írva részeként BUGSLAYERUTIL.DLL könyvtárban. Ez nagyban rövidített változata API szimbolikus DBGHELP.DLL gép. de rendelkezik néhány további funkciók, hogy megfeleljen a kihívásoknak régebbi verziói IMAGEHLP.DLL szimbolikus gépek. SYMBOLENGINE.H forráskód mutatja abban az esetben kell használni ezt az osztályt a régi karakter gépek I MAGEHLP.DLL.

Listng4-7 .Fayl SYMBOLENGINE.H

"Hibakeresés Applications" (Microsoft Press)

Ez az osztály - egy rövidített változata a karakter DBGHELP.DLL gép. CNN csak azokra a funkciókra, amelyek egyedi értéke fogantyú leíró. A többi funkció a gép karakter DBGHELP.DLL globális, így azok nem tartoznak ebbe az osztályba.

Annak megállapítására, ez az állandó osztály nem fog működni a hiba SymGetLineFromAddr keresnek, akkor PDB fMile nem az első keresést.

Annak megállapítására, ez az állandó, ez az osztály fogja használni egy másik módszer inicializálása jellegű gép - BSUSymlnitialize a BUGSLAYERUTIL.DLL. Ezen túlmenően, a rögzítés folyamatát doboz működni kezd minden 32 bites Windows-rendszerek. Ha ezt a meghatározást, kivéve SYMBOLENGINE.N kell tartalmaznia BUGSLAYERUTIL.H fájlt.

// Ha be vagy IMAGEHLP.DLL vagy DBGHELP.DLL.

// Tartalmazza ezen irányelvek az esetben, ha a felhasználó elfelejti

// az elrendezés a megfelelő könyvtárak

#pragma üzenetére (lib, "dbghelp. lib")

#pragma üzenetére (lib, "változat, lib")

// A nagy ötlete wrapper osztályok struktúrák

// három dimenziós mező, jött ember újságíró MSJ Fields

// (Paul DiLascia). Köszönöm, Paul!;

// Nem tartalmazza az osztály állandó IMAGEHLP_SYMBOL, mert

// változó méretű szerkezetet.

struct CImageHlp_Module. nyilvános IMAGEHLP_MODULE

memset (e, NULL, sizeof (IMAGEHLP_MODULE));

SizeOfStruct = sizeof (IMAGEHLP_MODULE);

struct CImageHlp_Line. nyilvános IMAGEHLP_LINE

memset (e, NULL, sizeof (IMAGEHLP_LINE));

SizeOfStruct = sizeof (IMAGEHLP_LINE);

// Az osztály jellege a gép osztály CSymbolEngine

Public-konstruktor és destruktor

// Ennek használatához osztály, hívja a módszer Symlnitialize

// inicializálja a karakter a gép, majd a más módszerekkel

// helyett megfelelő szerepét DBGHELP.DLL

virtuális -CSymbolEngine (void)

Kiegészítő információk nyilvánosságra funkció

// Visszaadja a használt változat DBGHELP.DLL fájlt.

// konvertálni a visszaadott értékeket olvasható formátumban,

// paraméter szVer tartalmazni fog egy sort: 5.00.1878.1

BOOL GetlmageHlpVersion (DWORD dwMS, DWORD dwLS)

return (GetlnMemoryFileVersion (_T ( "DBGHELP.DLL"),

BOOL GetDbgHelpVersion (DWORD dwMS, DWORD dwLS)

return (GetlnMemoryFileVersion (__T ( "DBGHELP.DLL"),

// Visszaadja a változat a DLL-fájl olvasási PDB.

BOOL GetPDBReaderVersion (DWORD dwMS, DWORD dwLS)

// először ellenőrizte MSDBI.DLL fájlt.

if (TRUE == GetlnMemoryFileVersion (_T ( "MSDBI.DLL"),

else if. (IGAZ == GetlnMemoryFileVersion (_T ( "MSPDB60.DLL"),

// Most volt a sor, ellenőrizze MSPDB50.DLL.

visszatéréshez (GetlnMemoryFileVersion (_T ( "MSPDB50.DLL"),

// Munka függvény előző két funkciót.

BOOL GetlnMemoryFileVersion (LPCTSTR szFile,

HMODULE hlnstlH = GetModuleHandle (szFile);

// A teljes fájl nevét letöltött verzió

TCHAR sz mageHlp [MAX_PATH] !;

GetModuleFileName (hlnst-IH, szImageHlp, MAX_PATH);

// A méret a verzió információkat.

dwVerSize = GetFileVersionlnfoSize (szImageHlp.

ha (0 == dwVerSize)

// A méret a verzió információkat, és most kap

LPVOID IpData = (LPVOID) új TCHAR [dwVerSize];

if (HAMIS == GetFileVersionlnfo (szImageHlp.

dwVerlnfoHandle. dwVerSize. IpData))

törölni [] IpData; visszatérő (HAMIS);

// Egy egyedi érték, amelyeket használni fognak erre

// Például szimbolikus gépek. Ez az érték ne legyen

// az érték a tényleges folyamat, hanem egyszerűen - egy egyedi értéket.

Telepítése DBGHELP.DLL - csak egy része a történetnek, mert ahhoz, hogy betölti a szimbólum fájlok, akkor biztosítani kell, hogy a rendelkezésre álló, hogy a karakter a gép. Abban az esetben, szimbolikus gép DBGHELP.DLL DBG-fájlt fogja keresni azokat a következő helyeken:

  • aktuális könyvtárat használja DBGHELP.DLL (nem rosszabb debugger!);
  • változó _NT_SYMBOL_PATH környezetben;
  • változó _NT_ALT_SYMBOL_PATH környezetben;
  • Változó SYSTEMROOT környezetben.

Katalógusok, amelyek azt jelzik, környezeti változók, úgy kell megszervezni, egy bizonyos módon. Például, ha az alkalmazás áll EXE és DLL pár. könyvtárban található: C: \ MyFiles, akkor a könyvtár alatt létre kell hozni a következő alkönyvtárrendszert:

  • C: \ MyFiles
  • C: \ MyFiles \ szimbólumok
  • C: \ MyFiles \ szimbólumok \ Exe
  • C: \ MyFiles \ szimbólumok \ Dll

Két nemrégiben alkönyvtár elhelyezésére tervezett mindenkori alkalmazás DBG-fájlokat.

Az egyetlen különbség, ha dolgozik, PDB-fájlok, hogy a karakter fog keresni egy autó DBGHELP.DLL PDB -files az elsődleges alkalmazás könyvtárba, és próbálja meg betölteni az EKT ebből a könyvtárból. Ha a karakter DBGHELP.DLL gép nem lesz képes letölteni PDB-fájlok a könyvtárban, akkor próbálja keresni és letölteni őket csak a DBG-fájlok (pl. E. Ugyanabból alkönyvtárakat, ami kellett létrehozni tárolására debug fájl karakter).

Azaz, minden típusú pályázatát fájlokat egy külön alkönyvtárba DBG-fájlokat. - Szerk.

Hol vannak tárolva a bináris fájlokat az alkalmazás és a megfelelő PDB-fájlok, amelyek által létrehozott összekötő szakaszában hibakeresés épít. - Szerk.

Szerencsére mindannyiunk számára, nem kell írni az egyéni kódot át a köteget. A DBGHELP.DLL felvette egy speciális API-funkció stackwalk. amely gondoskodik az összes munkát a verem. WDBG használja ugyanúgy mint ahogy a C ++ hibakereső Vizuális. Csak az a baj - Nincs részletes dokumentációt stackframe szerkezetét. Listing 4-8 mutatják, csak azokon a területeken, ez a struktúra, amelyet ki kell tölteni. stackwalk funkció így is gondoskodott összes részletet nem lehet tudni, hogy az optimalizált kódot a verem át lehet elég nehéz feladat. Az ok ezeket a nehézségeket abban a tényben rejlik, hogy egyes funkciók a fordító végezhet optimalizálás távol a verem terület, azaz a. E. A hely, ahol tolta ki annak elemeit. Fordítóprogramok Visual C ++ és Visual Basic elég agresszív amikor végre optimalizálás, és ha tudják használni egy halom regiszter mint munkavállaló, akkor fogják csinálni. Munkájának megkönnyítése, a verem az ilyen helyzetekben, a fordító generál egy úgynevezett adat FPO (Frame Pointer kihagyása). FPO-adatok - a táblázat, amely stackwalk funkció kiszámításához használt feldolgozásával kapcsolatos azon funkciók, amelyek hiányoznak a normál terület a verem. Úgy véljük FPO-adatok azért is, mert rájuk hivatkozásokat néha előforduló MSDN és a különböző hibakereső. Lehetőség van, hogy többet tudjon a szerkezet FPO-WINNT.H adatállományban.

Listing 4-8. InitializeStackFrameWithGontext a i386CPUHELP.C

BOOL CPUHELP_DLLINTERFACE _stdcall

InitializeStackFrameWithContext (stackframe * pStack,

ASSERT (FALSE == IsBadReadPtr (pCtx, sizeof (kontextus)));

ASSERT (FALSE == IsBadWritePtr (pStack, sizeof (stackframe))

if ((TRUE == IsBadReadPtr (pCtx, sizeof (kontextus))) ||

(TRUE == IsBadWritePtr (pStack, sizeof (stackframe))))