Egyszerű POSIX alkalmazás Windows alatt

A Windows a kezdetek óta több fejlesztői API-t mutat, így lehet a Win32 API (mostanában már Windows API-nak hívják) függvényeit használó meg a POSIX API függvényeit használó programokat egymás mellett futtatni. Vista óta a POSIX-os alrendszert Subsystem for Unix-based Applications (SUA) néven emlegetik.

Itt van egy egész jó bevezető róla: Subsystem for Unix-based Applications (SUA): Orientation for Users, Administrators and Developers

Indulásként engedélyezni kell Windows funkciók között, majd le kell tölteni a megfelelő SUA csomagot (Utilities and SDK for Subsystem for UNIX-based Applications in Microsoft Windows 7 and Windows Server 2008 R2), amiben benne vannak az alap programok. Azért azt nem szabad elfelejteni, hogy ez UNIX-szerű és nem Linux környezet, tehát pl. C meg Korn shell van benne és nem bash, de azért a Tool Warehouse-ból elég sok egyéb programot le lehet szedni. Én nem használom rendszeresen, részletes tapasztalataim nincsenek vele, csak az Operációs rendszerek tárgy keretében akartam megnézni, hogy jelenleg hogy működik.

Az alap elv ugye az, hogy a környezeti alrendszerek (Windows, POSIX, régen az OS/2) mutatnak egy API-t a fejlesztőknek, és ezen kívül van egy belső, nem dokumentált rendszerhívás API, amit az OS nyújt:

image

Ha kicsit részletesebben megnézzük, akkor egy alrendszer a következőkből áll:

  • alrendszer folyamat (Windows: csrss.exe, SUA: psxss.exe),
  • alrendszer DLL (Windows: pl. a kernel32.dll, de több másik is, SUA: psxdll.dll).

Az alrendszer DLL-t linkeljük hozzá az alkalmazásunkhoz, és ez hív tovább az NT API megfelelő függvényébe (ntdll.dll-ben). Az alrendszer folyamat tartja nyilván az alrendszerhez tartozó folyamatokat, de a pontos szerepéről túl sok információt nem találtam. A CRK-ban is csak ennyi van:

    • API DLLs
      • Export the APIs defined by the subsystem
      • Implement them by calling Windows “native” services, or by asking the subsystem process to do the work
    • Subsystem process
      • Maintains global state of subsystem
      • Implements a few APIs that require subsystem-wide state changes
        • Processes and threads created under a subsystem
        • Drive letters

Ha fogunk egy nagyon triviális Hello World programot C nyelven, és azt lefordítjuk a SUA alatt, akkor a DependencyWalker a következő függőségeket mutatja:

test-posix-api

A test nevű programom a psxdll.dll-t használja, az pedig az ntdll.dll-t. Alul a modulok résznél érdemes megnézni, hogy a testhez azt írja ki, hogy ez a posix console alrendszerhez lett lefordítva. Ha elindítjuk az alkalmazást, Process Explorerben ezt látjuk:

hello-dlls

 

A folyamatunk használja még az ld.so (dynamic linker/loader) és a libc.so (standard C library) megosztott könyvtárakat. Ezen kívül itt most látszik az összes fontos egyéb folyamat: a session manager (smss.exe) által elindított pxsss.exe, és a posix.exe (ami a posixos alkalmazások konzol kezelését végzi).

WinDbg alatt pedig a következő stack trace-t látjuk, ha egy fájl olvasás közben egy breakpoint segítségével megállítjuk a futást:

ntdll!ZwReadFile
PSXDLL!PsxDllDevReadUpdate+0x1d
PSXDLL!read_ex+0xb6
PSXDLL!read+0x15
WARNING: Stack unwind information not available. Following frames may be wrong.
libc_so_5+0x2b5ef
libc_so_5+0x2b69b
libc_so_5+0x1f64f
libc_so_5+0x5a76
hello+0x1b52
hello+0x102c
hello+0x11fb
PSXDLL!PdxProcessStartup+0x2c

A programunk meghívja a standard C könyvtár megfelelő függvényét, majd az az alrendszer dll-t, az pedig végül az ntdll.dll adott függvényével hívja meg a keresett rendszerhívást. Nem találtam olyan opciót a SUA-ban lévő gcc-nél sem, ami pdb fájlokat készítene a debug szimbólumokkal (a pdb elég Windows specifikus), ezért nem látszanak a függvény nevek a hello-ban. Generál viszont olyan debug információt, amit meg a gdb fel tud használni, gdb alatt így néz ki a hívási lánc:

#0  0x773f64f4 in ?? ()
#1  0x71de0566 in ?? ()
#2  0x71de1d0c in ?? ()
#3  0x77dab5ef in __sread () from /usr/lib/libc.so.5.2
#4  0x77dab69b in _sread () from /usr/lib/libc.so.5.2
#5  0x77d9f64f in __srefill () at msize.c:73
#6  0x77da849d in __srget () at msize.c:73
#7  0x77d8e21e in gets () at ftol2.asm:141
#8  0x00401ae6 in main () at hello.c:6

Itt meg a posixos részhez vannak pontos függvényneveink, de mivel ez egy POSIX-es alkalmazás, ez meg a Windowsos dll-eket nem ismeri:) Visual Studio-hoz van debugger add-in a SUA-ban, azzal azt hiszem lehet mindkét részt látni, de nem próbáltam most ki.

A lényeg, hogy amire az elején kíváncsi voltam, viszont kiderült: POSIX alrendszert használó program alatt is ugyanúgy néz ki a hívási lánc, mint a Windows alrendszert használónál.

 

Reklámok
Kategória: Opre
Címke: ,
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