Archive for September, 2014

Már csak 2 napig lehet extra kedvezménnyel jelentkezni a TDD tanfolyamra! 200000 -> 150000

Monday, September 29th, 2014

Itt érhető el az online jelentkezési lap.

Már csak 4 napig lehet extra kedvezménnyel jelentkezni a TDD tanfolyamra! 200000 -> 150000

Friday, September 26th, 2014

Gyorsan, gyorsan, ne maradjatok le róla.

Gyors beszúrások sql server táblákba

Wednesday, September 24th, 2014

Nagyon jó kis lista, a 610-es trace flagről nem tudtam, nem is értem miért dugdossák, marha hasznosnak tűnik. A 11-es megoldás is trükkös benne.
(Utólag visszaolvasva az utolsó mondatot ez tiszta olyan lett, mint a facebook like gyűtő szövegek. :)

TDD tanfolyam újra – extra előfoglalási akcióval

Monday, September 22nd, 2014

Újra lesz TDD tanfolyam novemberben. Aki gyorsan lép, sokkal olcsóbban jöhet most tanulni.

Részletek itt, várok mindenkit szeretettel.

Belassuló webszerver nyomozás

Thursday, September 18th, 2014

Nyáron két érdekes és nehéz esetem is volt ügyfeleknél, mindkettőhöz memory dumpokat is kellett elemezni WinDbg-gal. Elmesélem az elsőt.

Ebben teljesen kiszámíthatatlan módon felment a webszerver cpu-ja 100%-ra, és nagyon belassult a kiszolgálás raja. A procit a w3wp.exe vitte el, azaz nem valami megőrült vírusirtó vagy egyéb más ártalmas processz. Sajnos az elején ez a tény, hogy nagy cpuval jár együtt a belassulás nem volt még egyértelmű, így nem ebbe az irányba kezdődött a nyomozás.

DynaTrace agent fel volt telepítve a szerverekre (okos kis cucc), ami alapján látszottak a kérésekhez tartozó stack trace-ek és .NET statisztikák is. Az alapján vagy a webapp -> web service hívások voltak lassúak, vagy a GC vitt el túl sok időt. A hálózati és szerviz problémát egy idő után ki lehetett zárni, mivel a szerviz oldalon pár ms alatt lefutottak a hívások. A .NET hálózati traceinget is bekapcsoltuk, hogy webapp oldalról milyen időkkel mennek a hívások, de ebben minden infó benne volt, csak a timestampek nem. Nesze semmi fogd meg jól.

A GC ügyre nem tudtam semmit mondani. Egészen pontosan a DynaTrace Suspensiönt mutatott, azaz valamire várakoztak a szálak. A doksija szerint ez általában GC-re várakozást jelent. Általában. A .NET GC perfmon counterek ezt nem erősítették meg. A hálózatra és egyéb IO-ra várakozás külön tétel volt a listán, így a suspension oka rejtély maradt. A memory dumpok nem segítettek, mivel mind olyankor készült, amikor már rendben volt a gép, apppol recycling miatt.

Szerencsére a tesztelő kolléga nagyon lelkesen segítkezett, és a tesztjeivel sikerült reprodukálni a problémát. Hogy pontosabban lássuk, mi történik, felraktunk egy gépet a staging szerverre, így úgy tudtunk mérni profilerrel, mi történik a worker processzben.

Amikor végre sikerült reprodukálni a hibát, végre saját szememmel láttam, hogy a cpuk kiülnek 100%-ra, és odaragadnak. Annyira le volt terhelve a gép, hogy nem is lehetett használni a profilert, task managerben el kellett vennem a processor affinity-n keresztül pár procit a w3wptől, hogy a visual studio egyáltalán meg tudjon nyekkenni.

A profiler már közelebb vitt a problémához, az idő zöme a Dictionary.FindEntry metódusában ment el.
Ezt hívja a TryGetValue, a ContainsKey és az Indexer, ez a fő kereső része. Mivel a Dictionary arról híres, hogy igen gyors, arra gondoltam csak azért megy el itt annyi idő, mert végtelen cilusba kerül a Dictionaryt hívó kód, valamilyen kódszervezési hiba miatt. Ezért raktunk a kódba egy számlálót, hányszor hívják meg a Dictionary-t piszkáló metódust, és kilogoltuk a % 1000000-dik hívást. Vártunk, vártunk, de nem keletkezett log.

Ekkor némi guglizás után találtam rá erre a cikkre. És ekkor minden összeállt. A Dictionary nem thread safe, csak olvasásra. Ha több szál egyszerre írja és olvassa is, akkor beakadhat végtelen ciklusba a FindEntry metódus!!!

Ez itt kérem a szopóroller:

for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) 
{
    if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
}

Ez a for soha nem ér véget, extrém ritka versenyhelyzet esetén. Aljas, nem?

Mi a megoldás? Meg kell írni a kódot thread safe-re, lock-kal és egyebekkel.

A DynaTrace suspension idő ebből következően a thread cpura várakozást jelenette, annyira le volt fogva minden cpu, hogy az os kénytelen volt elvenni magot a szálaktól, ez látszott suspensionként a riportokban. Tessék békén hagyni szegény GC-t, mindig ő a bűnbak. :)

Mit tennék másképp, hogy a következő esetben célratörőbben találjam meg a problémát?

1. Sokkal szigorúbban oda kell figyelni a makró adatok rögzítésére. A performance counterek nagyon jó hátteret adnak, de ehhez tényleg napokig futtatni kell a perfmont, és megőrizni a logokat a nyomozás végéig.

2. Semmit nem kell elhinni, mindent magunknak kell megnézni. Pl., hogy a dump tényeg akkor készült-e, amikor még fennállt a hiba, másképp könyékig turkálhatunk a dumpban, nem lesz benne semmi érdekes.

3. Ha sikerül azonosítani a hiba indikátorát, pl. nagy cpu, lassú lapvégrhajtás, exceptionök, stb., akkor automatikus dumpokat kell készíteni, nem embereket zaklatni ezzel. A Debug Diagnostic Tool v2.0 erre van kitalálva.

4. Nagy erőfeszítéseket kell tenni, hogy rerpodukálni lehessen a hibát olyan környezetben, ahol van Visual Studio, így debugger és profofiler. A dump egy pillanatot kap el, memória és néha cpu elemzésre is jó, de mivel csak egy pillanat látszik belőle, nehéz összerakni a nagy képet.

Éjszakai gép felébredés megakadályozása

Tuesday, September 16th, 2014

Elegem lett abból, hogy minden reggel ébren vár a gép, hiába altatom el este. Egyesével macerás letiltani az ébresztő eszközöket, ezért írtam egy kis egysoros powershell scriptet, ami mindet letiltja. Adminként kell futtatni:

powercfg -devicequery wake_programmable | foreach {powercfg -devicedisablewake $_}

Visual Studio Profiler .NET Framework belsejéhez

Monday, September 15th, 2014

Windows 8-n már nem látszanak a rendszerhívások a profilerben, mivel nincsenek pdbk a natívra lefordított .net rendszerkódokhoz, ez pedig kellene a profilernek (illetve, mivel nagyon más a profiler mögötti infrastruktúra a Windows 8 szigorúbb secuja miatt).

Itt leírják, hogy lehet ngenelt assemblykhez pdbt generálni.

Az első, source nélküli leírás nekem nem volt elég, a metódusnevek helyén valamilyen hash szerű érték jelent csak meg, az nem túl hasznos.

Hogy ne kelljen kézzel cicózni a sok assemblyvel, itt a megoldás.
Végigszántja a gacot, és nyomja hozzájuk a pdbket. Ráadásul megcsinálja 32 és 64 bitre is. Szeretjük a Wintellectet.

Visual Studio repair

Friday, September 12th, 2014

A tegnapi gépdöglődés után Visual Studio repair volt, mivel indulás után szórta a hibákat, melyik modulja nem megy. A sima repair a Programs and Feature-sből nem segített. Két dolgot tettem, amitől rendbe jött. Egyrészt felraktam az VS 2013 SP3-at, másrészt kitöröltem pár megsérült config fájlt (hogy melyik segített sajnos emiatt nem tudom behatárolni).

C:\Users\soci\AppData\Local\Microsoft\VisualStudio\12.0\devenv.exe.config
Másrészt itt ha valamelyik, az adott assemblyhez tartozó fájl megsérül, akkor se indul a buli:
C:\Users\soci\AppData\Local\Microsoft_Corporation\

Ha valami misztikus oknál fogva semmilyen .netes program nem megy egy gépen, akkor lehet a központi config beteg, ezek a környéken:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\

Értelemszerűen kell a verziót és a bitnesst nézni.

Furcsa hiba

Thursday, September 11th, 2014

Az egyik szerveren ahol Visual Studioban dolgozok mostanában instabillá váltak a dolgok. Például lefagyott a gép munka közben, újraindulás után pedig miden fájl, ami meg volt nyitva visual stdioban, az nulla hosszúságúra csonkolódott le. Nem röhögtem hangosan.
Először a C meghajtóra gyanakodtam, de a hiba ravaszabb volt, mint gondoltam. Volt a gépben egy olyan merevlemez, ami már döglődött. Erről tudtam, igyekeztem nem hozzányúlni. Ugyanis egyes fájlok esetén beragadt az olvasás, és sok percig nem lehetett semmit csinálni a processzel (az IO-ba befagyó processzeket nem tudja a Windows elpusztítani (max systemként a kommentek alapján)).

Lassan széthullt a VS (még most is repair-elem), a windowst sfc /scannow-val ellenőriztettem, meg volt sok chkdsk is. Minden oknak tűnt, de a hiba megmaradt.

Kivettük a beteg vinyót, hogy tisztán lássuk, mitől vannak csúnya, nem tudom olvasni a hddt bejegyzések az event logban. Újraindítás után lepett meg a Windows: nincs meg a korábbi page file-ja. Ezen a beteg drive-on volt a pagefile! Ez okozta a misztikus adatvesztést és leállásokat. Ah…

Most megy a vs repair, de egyelőre ez sem olyan egyszerű, mint gondolnánk, majd írok róla.