PDB fájl generálása MS C/C++ fordítóval

Egy nagyon egyszerű Hello world alkalmazást akartam lefordítani Windows 7 alatt, ami beolvassa egy fájl tartalmát a ReadFile Windows API hívással, hogy utána WinDbg segítségével lehessen követni, hogy hogyan halad a kérés a kernel32 és ntdll DLL-eken keresztül a kernel rendszerhívása felé. A Windows SDK Simple nevű mintapéldának a fájljait használtam ehhez: van egy Simple.c nevű forrásfájl és egy Makefile (ennél egyszerűbb tényleg nem is lehetne:).

Elindítottam a Windows SDK Command promptot, az szépen beállította a környezeti változókat x64-es DEBUG módnak megfelelően. Az nmake elvégezte a fordítást és a linkelést, azonban a végén csak az EXE, az object fájl és egy vc90.pdb keletkezett, simple.pdb pedig nem:( Ez azonban később kellene nekem, hogy a debugger tudja, melyik függvényében jár a simple programnak. Megpróbáltam csak simán a fordítót meghívni:

cl /Zi Simple.c

Így pedig elkészült a simple.pdb is, tehát valahol a Makefile-ban van a gond. Elkezdtem nézegetni a cl fordító paraméterezését, hát, van egy pár lehetőség:). Az nmake ezt a kimenetet adta, ebből kéne visszakövetni, hogy mi micsoda:

C:\Users\meres\Desktop\windows-api>nmake
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

if not exist "WIN7_X64_DEBUG/" mkdir WIN7_X64_DEBUG
cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64
-D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0601 -DNTDDI_VERSION=0x
06010000 -D_WIN32_IE=0x0800 -DWINVER=0x0601 -D_MT -MTd /WX /Zi /Fo"WIN7_X64_DEB
UG\\" /Fd"
WIN7_X64_DEBUG\\" simple.c
simple.c
link /INCREMENTAL:NO /NOLOGO -subsystem:console,6.1 -out:WIN7_X64_DEBUG
\simple.exe WIN7_X64_DEBUG\simple.obj kernel32.lib ws2_32.lib mswsock.lib advap
i32.lib
copy read.Txt WIN7_X64_DEBUG
1 file(s) copied.

Az MS C/C++ fordítót keveset használtam, így eltartott egy ideig beazonosítani a dolgokat. Végül megnéztem, hogy az nmake honnan szedi, hogy milyen kapcsolókat használjon: a Win32.Mak fájlban tárolja a közös beállításokat. Ez egy 600 sornyi környezeti változó beállítás attól függően, hogy épp debug vagy release módot meg milyen architektúrát használunk. Szerencsére az elején van egy quick start, hogy miket kéne használni:

#  ---------------------------------------------------------------------------
#   To build:         |  Compiler Options      | Linker options (pick one
#                     |                        | line. con = console,
#                     |                        | gui = GUI, ole = GUI OLE)
#  ---------------------------------------------------------------------------
#  Single threaded    | cdebug cflags cvars    | ldebug guilflags guilibs
#  app with static    |                        | ldebug conlflags conlibs
#  CRT                |                        | ldebug guilflags olelibs
#  ---------------------------------------------------------------------------

Megnézve a Simple alkalmazáshoz adott Makefile-t végre feltűnt, hogy a linkertől lehagyták az ldebug részt, így az nem használta a /debug kapcsolót. Ezon kívül a compilernél is explicite berakták a /Zi kapcsolót, ahelyett, hogy a cdebug változót használták volna. A Makefile-nak tehát szerintem így kéne kinézni:

# Nmake macros for building Windows console apps
# statically links the C Run-Time Libraries (CRT)

!include <Win32.Mak>

all: $(OUTDIR) $(OUTDIR)\simple.exe

#----- If OUTDIR does not exist, then create directory
$(OUTDIR) :
    if not exist "$(OUTDIR)/$(NULL)" mkdir $(OUTDIR)

$(OUTDIR)\simple.obj: simple.c
$(cc) $(cflags) $(cvars) $(cdebug) /WX /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\" simple.c

$(OUTDIR)\simple.exe: $(OUTDIR)\simple.obj
$(link) $(conflags) $(ldebug) -out:$(OUTDIR)\simple.exe $(OUTDIR)\simple.obj $(conlibs)

#--------------------- Clean Rule -------------------------------------------------------- # Rules for cleaning out those old files clean: $(CLEANUP)

Így most már generálta a simple.pdb-t is. Itt megtaláltam, hogy pontosan hogyan is keletkezik a PDB fájl, és miért készül két darab belőle: PDB Files (C++). Tehát ha a /c segítségével csak object fájlokba fordítunk, akkor a /Zi hatására a cl.exe készít egy VCx0.PDB fájlt, amibe belerakja az object fájlok szimbólumait. Aztán pedig a /debug hatására a linker készíti el ezekből az exe-hez tartozó PDF fájlt (hisz a fordító még nem tudhatja, hogy mi lesz az exe neve). Így már világos, hogy elsőre miért nem készült el a simple.pdb:)

Reklámok
Kategória: Opre | Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s