Daily Archives: 2009.09.1. 19:48

PDB fájlok a webszerveren

Nemrég készítettem egy webalkalmazást, ami egy solutionben volt egy Class Library típusú projekttel. Fordítgatás után feltűnt, hogy Release módban is ott virít a bin mappában az osztálykönyvtár DLL-jéhez tartozó PDB fájl. Vajon kell ez egy production szerverre?

Annyit nagyjából mindenki tud a PDB fájlokról, hogy valami debuggoláshoz használatos izé, meg biztos jó, ha van. Akit jobban érdekel, hogy mi van benne, annak feltétlenül tudom ajánlani John Robbins PDB Files: What Every Developer Must Know című cikkét. Akit annyira nem érdekel (és egyébként annyira talán nem is érdekes), annak itt a lényeg:

  • A PDB fájlokat nem szokás nézegetni, majd a Visual Studio kiszedi belőle azt, ami kell neki.
  • Lényegében az van a PDB fájlban, hogy a DLL-hez hol van a forráskód és az egyes utasítások azon belül melyik sorban vannak.
  • A PDB fájlok nem csereberélhetők az egyes DLL verziók között még akkor sem, ha két fordítás között a DLL forráskódja egy bitnyit sem változott. A DLL-t és a PDB-t egy közös GUID köti össze, ami minden fordításnál változik.
  • Ebből következik, hogy ha fontos, amit a PDB tud, akkor azt meg kell őrizni minden egyes buildnél, mert később nem lehet újra előállítani.

A kérdés már csak az, hogy Release konfigurációnál miért keletkezik PDB és hogy production környezetben szükség van-e erre a fájlra, vagy nyugodtan törölhető?

Próbaként alkottam egy Class Library-t, benne az alábbi osztállyal:

  public static class MyClass
  {
    public static void Boom()
    {
      throw new ApplicationException( "Külső kivétel.", 
            new IndexOutOfRangeException( "Belső kivétel." ) );
    }
  }

Majd hozzáadtam a solutionhöz egy Web Site típusú projektet, ahol a default.aspx-en belül meghívtam ezt a metódust így:

  protected void Page_Load(object sender, EventArgs e)
  {
      try
      {
          MyClass.Boom();
      }
      catch( Exception ex )
      {
          this.Response.Write( ex.ToString().Replace( "rn", "<br/>" ) );                
      }
  }

Az érdekelt, hogy mennyire részletes a kimenet. Alapesetben volt PDB fájl a webalkalmazás bin mappájában, kimenetként ezt kaptam:

System.ApplicationException: Külső kivétel. —> System.IndexOutOfRangeException: Belső kivétel.
— End of inner exception stack trace —
at ClassLibrary1.MyClass.Boom() in W:SystemDesktopDeployTestSolutionClassLibrary1MyClass.cs:line 12
at _Default.Page_Load(Object sender, EventArgs e) in w:SystemDesktopDeployTestSolutionMyWebDefault.aspx.cs:line 16

Miután kitöröltem vagy átneveztem a PDB fájlt (a DLL-hez nem nyúltam) már csak ennyi volt a hibaüzenet:

System.ApplicationException: Külső kivétel. —> System.IndexOutOfRangeException: Belső kivétel.
— End of inner exception stack trace —
at ClassLibrary1.MyClass.Boom()
at _Default.Page_Load(Object sender, EventArgs e) in w:SystemDesktopDeployTestSolutionMyWebDefault.aspx.cs:line 16

Tehát a DLL-ről már nem tudjuk, hogy pontosan melyik sorban hibás. Ha erre nincs szükségünk, akkor a Project properties –> Build –> Advanced (legalul eldugva) gombra megjelenő Advanced Build Settings ablakban megkérhetjük a Studiót, hogy kíméljen meg a PDB fájloktól:

Advanced build settings ablak

Ez egyébként annyit tesz, hogy a project fájlunkba a következőt írja: <DebugType>none</DebugType>

Ha parancssorból fordítunk, akkor ugyanezt a hatást érhetjük el akkor, ha az MSBUILD utasítás végére a /p:DebugType=none kapcsolót illesztjük.

Mi a helyzet a webalkalmazással?

Az nyilvánvaló, hogy a compilation debug=”true” kapcsoló a web.configban erre is vonatkozik, false értéknél már csak ennyi a kimenet (PDB nélkül):

System.ApplicationException: Külső kivétel. —> System.IndexOutOfRangeException: Belső kivétel.
— End of inner exception stack trace —
at ClassLibrary1.MyClass.Boom()
at _Default.Page_Load(Object sender, EventArgs e)

Szinte biztos, hogy nem akarjuk az egész alkalmazást debug módban használni, mégis előfordulhat, hogy szükségünk lenne részletes stack trace-re és sor számokra. Ez esetben marad a parancssori fordítás, ahol a –d kapcsolóval kérhetünk PDB fájlokat (a MyWeb a forráskönyvtár a MyWebCompiled pedig a cél):

aspnet_compiler -v / -p MyWeb -f -d MyWebCompiled

Íme a kimenet a webalkalmazás bin mappájában:

aspnet_compiler-d_bin

Ezek után már átírhatjuk a debug attribútumot false értékre, a stack trace-ben megmaradnak a részletes információk.

Technorati-címkék: ,,,,

A közoktatási szoftver

Az alábbi bejegyzés megírása után további információkat kaptam, amit végén lévő kiegészítésekben foglaltam össze. A teljes kép érdekében azokat is célszerű elolvasni.

Úgy látszik a szoftverek terén is következmények nélküli ország vagyunk, simán rá lehet tukmálni az ország felsőoktatási intézményeire egy ilyen szoftvert (a nevét kicsillagoztam):

“Az adminisztrációs kliens működésében hiba lépett fel. Emiatt bizonyos munkaállomásokon "hálózati kommunikációs hiba" üzenetet kaptak a felhasználók. A hiba javítható, ha az illetékes kari/tanszéki rendszergazda letölti és telepíti a honlapunkról az admin klienst.

A telepítés lépései röviden:

1. meglévő ******.kari/******.tanszeki kliens mappa letörlése

2. a kliens letöltése a honlapunkról és kitömörítése a C: meghajtó gyökérkönyvtárába

3. a felhasználóknak teljes hozzáférést kell adni a kitömörített könyvtár teljes tartalmára”

És ez egy olyan szoftver, amit az országban több ezer gépen kötelező telepíteni.

Lehet, hogy furcsa elvárásaim vannak, de szerintem

  • egy alkalmazásnak legyen telepítője
  • a telepítő legyen automatizálható, különösen, ha sok gépre kell telepíteni
  • egy ilyen jellegű alkalmazás frissítse önmagát
  • egy alkalmazás sem feltételezheti, hogy van C: meghajtó a gépemben
  • egy alkalmazásnak semmi keresnivalója egy meghajtó gyökérkönyvtárában
  • egy átlagos felhasználónak (jelen esetben tipikusan titkárnőnek) ne legyen írási joga a program könyvtárakra

Mindez ráadásul utólag, ami gyanítom, hogy nem a helyi IT sara, én inkább a fejlesztőkre fogadnék. Komoly munka lehet egy .NET-es alkalmazást ennyire bénán megírni…

Kiegészítés (2009.09.01.)

Az érkezett hozzászólások és az időközben tudomásomra jutott információk alapján a szóban forgó kliens automatikus frissítéssel rendelkezik, tetszőleges helyről és meghajtóról fut, tipikus installer pedig az intézmények sokszínűsége miatt nincs. Jelen esetben úgy tűnik, hogy konfigurációs hiba történt, ami nem a fejlesztők vagy a szoftver hibája.

Kiegészítés (2009.09.14.)

Telefonon a legfőbb helyről kaptam bővebb technikai információkat ennek a hibának a hátteréről, ami a teljesség kedvéért mindenképp ide kívánkozik:

  1. A szóban forgó kliens képes frissíteni önmagát.
  2. A kliens a frissítéshez olyan technológiai megoldást használ, amit a Microsoft is a legkorszerűbbek közé sorol.
  3. A frissítés általában jól működik, hiszen havonta-két havonta minden gond nélkül megtörténik.
  4. A szóban forgó frissítés a többi intézményben hiba nélkül települt.
  5. A problémát a helyi IT részéről konfigurációs hiba és változáskezelési hiányosságok okozták.
  6. A fenti idézet forrása a helyi IT, nem a fejlesztő cég.