Category Archives: Development Tools

Advanced Debugging Stories .NET – záznam, dema a slides [WUG Praha 4/2016]

Slides a dema z mé přednášky pro setkání WUG Praha z 12.4.2016:

Záznam z přednášky je publikován na našem HAVIT YouTube Channel.

Dotčená témata a nástroje

  • Windows Debugger + SOS.dll extension
  • Memory Dump Analysis, Crash Dump Analysis
  • DebugDiag, ClrProfiler
  • Microsoft Diagnostics Runtime
  • Stack analysis
  • Heap analysis, Garbage Collection, Finalization
  • StackOverflow

Fiddler: Zachytávání WCF SOAP volání localhost služby

Pokud ladíte projekt s WCF client-server komunikací (WCF SOAP), může se hodit možnost zachytávat tuto komunikaci ve Fiddleru.

Mnoho návodů vám pomůže nastavit Fiddlera jako proxy, pokud chcete zachytávat komunikaci svého WCF clienta se vzdálenou webovou službou. Pokud však serverovou stranu sami vyvíjíte a běží vám právě na localhost, postup dle těchto návodů vám komunikaci nezachytí.

Je potřeba na straně WCF clienta nastavit adresu cílových endpointů pomocí “localhost.fiddler:port”, všude tam, kde dosud máte “localhost”:

<system.serviceModel>
    <client>
        <endpoint address="http://localhost.fiddler:12890/WebServices/MyService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService" contract="MyApp.IMyService" name="BasicHttpBinding_IMyService"/>
    </client>
</system.serviceModel>

Fiddler: Ignorování requestů (šumu na pozadí)

Kde jsou ty časy, kdy člověk pustil Fiddler Web Debugger a mohl v něm poklidně ladit svojí webovou aplikaci, aniž by se musel probírat stovkami HTTP requestů generovaných ostatními aplikacemi. Dnes je HTTP protokol natolik oblíbený, že použití Fiddler již není tolik pohodlné.

Naštěstí je možné Fiddlerovi říct, jaké requesty má ignorovat (resp. skrýt z UI, “odbavení” nadále provádí). Děje se tak např. prostřednictvím FiddlerScriptu, kde ve funkci OnBeforeRequest můžeme nastavit (výstřižek ze začátku funkce):

    static function OnBeforeRequest(oSession: Session) {       
      
        if (
            (oSession.hostname == "tfs.havit.eu")
            || (oSession.hostname == "outlook.office365.com")
            || (oSession.hostname == "havit.sharepoint.com")
            || (oSession.hostname == "tfs.havit.eu")
            || (oSession.hostname == "vortex.data.microsoft.com")
            || (oSession.hostname == "nexus.officeapps.live.com")
            || (oSession.hostname == "client-api.itunes.apple.com")
            || (oSession.hostname == "iadsdk.apple.com")
            || (oSession.hostname == "roaming.officeapps.live.com")
            || (oSession.hostname == "mobile.pipe.aria.microsoft.com")
            || (oSession.hostname == "play.itunes.apple.com")
        ) {
            oSession["ui-hide"]="yup";
        }

        // pokračování funkce

            

FiddlerScript najdeme v menu Rules pod volbou Customize Rules… “Ideálně” se edituje prostřednictvím FiddlerScript Syntax Highlight doplňku (na jeho instalaci se ptá Fiddler při otevírání položky Customize Rules…):

image

Kromě oSession.hostname můžeme použít i plné oSession.url, nebo další možnosti poskytovaného FiddlerScript API.

[ASP].NET Worst Practices – záznam, slides a dema [Prague .NET Meetup 02/2016]

Slides a dema z mé přednášky pro setkání Prague .NET Meetup ze 17.2.2016:

Záznam z přednášky je publikován na našem HAVIT YouTube Channel.

Dotčená témata

  • Garbage Collector, Finalization, C# Destructors, Resource Wrapper pattern
  • Process Failure, StackOverflow, Windows Debugger, DebugDiag
  • <compilation debug=“true|false“ />, <deployment retail=“true“/>
  • ASP.NET Over-posting / Mass-assignment
  • skládání stringů vs. StringBuilder
  • vyhledávání v datech – List vs. BinnarySearch vs. Dictionary vs. LINQ ToLookup()
  • perly code-review

Advanced Debugging .NET – záznam, slides a dema [ShowIT SK 02/2016]

Slides a dema z mé přednášky pro konferenci Gopas ShowIT Bratislava z 10.2.2016:

Záznam z přednášky je publikován na našem HAVIT YouTube Channel.

Dotčená témata

  • StackOverflow troubleshooting
  • Windows Debugger, SOS, DebugDiag
  • Prozkoumávání zásobníku
  • Prozkoumávání haldy, rootů, finalization queue
  • GC Root identification (static fields)

Code Analyzers vs. generovaný kód

Pomocí analyzérů ve VS 2015 máme možnost kontrolovat programový kód různými pravidly ověřující štábní kulturu kódu. Netestuje se tedy, zda kód dělá to, co má, ale zejména to, jak je zapsán. Ale i to dokáže občas odhalit chyby v chování programu.
V aplikacích je však nejen kód ručně psaný programátory, ale často i kód generovaný různými nástroji (designer soubory od resources, aspx, atp.)

Takový kód často nesplňuje pravidla, které na vlastní kód klademe, a zároveň nemáme možnost způsob generování ovlivnit.

Jedno možností je použít global suppressions (viz Code Analysis na stránce https://www.visualstudio.com/en-us/news/vs2015-update1-vs.aspx), druhou možností je vypnout kontrolu generovaného kódu ve vlastnostech projektu.

codeanalysis

To však přináší zmatek v tom, co který analyzér považuje za generovaný kód. Pro určení, zda jde o generovaný kód používají různé nástroje různé techniky, například

  • dle pojmenování souboru
  • dle obsahu souboru – komentář s <auto-generated />
  • nebo dle obsahu souboru – attributy u třídy

StyleCop Analyzers

Jako generovaný kód označují kód souboru (zdroj):

  • jehož název končí na .designer.cs
  • nebo obsahuje v komentáři text <auto-generated či <autogenerated
  • nebo je soubor prázdný.

SonarLint for Visual Studio 2015

Jako generovaný kód označují kód (zdroj):

  • souboru, jehož název obsahuje .g., .generated., .designer., .generated., _generated. nebo temporarygeneratedfile_
  • nebo obsahuje v komentáři text <auto-generated či <autogenerated
  • nebo je třída odekorována atributem DebuggerNonUserCode, GeneratedCode, ExcludeFromCodeCoverage či CompilerGenerated.

Code Analyzers

Neobsahují žádnou logiku pro odlišení generovaných souborů od ostatních (nebo se mi ji alespoň v čase, který jsem hledání byl ochoten věnovat, žádnou nenašel).

(zdroj)

Srovnání analyzérů

Tabulka ukazuje, které analyzéry považují jaký soubor za generovaný (ano = generovaný, ne = nerozpoznáno):

.designer.cs
(název souboru)
// <auto-generated>
(obsah souboru)
[GeneratedCode]
(obsah souboru)
Code Analyzers  ne ne ne
StyleCop Analyzers ano ano ne
Sonar Lint ano ano ano

Visual Studio:“The XY has already been declared.“ (XSD)

Pokud ve Visual Studiu editujete XML soubory, ke kterým máte XSD schema, můžete se dočkat hlášek typu:

  • The global element ‚…‘ has already been declared.
  • The complexType ‚…‘ has already been declared.
  • apod.

XSD

Potíž je v tom, že Visual Studio se snaží schema XML souboru validovat vůči XSD souborům z celé solution (dle namespace). Pokud máte tedy odpovídající XSD soubor v solution vícekrát, výsledkem jsou výše uvedené kolize.

Update: XML Schemas

Zbyněk Řešetka (děkuji) mě nasměroval na původní správné řešení, o kterém jsem si myslel, že ve VS2015 zmizelo – dialog XML Schemas, kde si aktivní schema navolíte, i když máte XSD soubor v solution vícekrát:

 

Schemas.png

Přístupný je přes menu XML / Schemas… Záludnost, která mě zmátla, spočívá v tom, že toto menu existuje pouze pokud je otevřen XML soubor a nastavení schemat se nedá vyloudit ani přes Quick Launch.

Advanced Debugging Stories – záznam, slides a dema [MS Fest Praha 11/2015]

Slides a dema z mé přednášky pro konferenci MS Fest Praha z 29.11.2015.

Záznam je publikován na našem HAVIT YouTube Channelu:

Dotčená témata

  • Windows Debugger – SOS.dll
  • DebugDiag – Collection, Analysis
  • StackOverflowException
  • Stack analysis
  • instalace a zprovoznění WinDbg
  • získání memory-dumpu
  • Heap analysis
  • Finalize Queue, F-reachable Queue
  • Garbage Collector
  • rootování, GCRoot
  • statické fieldy

WinDbg: Trvalá změna výchozího fontu popř. dalších nastavení

WinDbg (Windows Debugger) má svá specifika. Představuji si to asi tak, že když už byl příslušný tým v Microsoftu po několika marných pokusech dotlačen k vytvoření GUI nad konzolovou podobou (jedinou pravověrnou), rozhodl se to udělat tak, aby vzniklá GUI nadstavba opravdu nikoho nelákala se do debuggingu na této nízké úrovni pokoušet.

Jedním ze specifik tak například je, že zatímco v každé jiné aplikaci pokud změníte velikost písma a podobné volby UI, pamatuje si to aplikace i do příštího spuštění, aniž byste to museli nějak řešit.

Ve WinDbg tomu tak není.

Dlouho jsem si dokonce myslel, že to nějak souvisí s novými vymoženostmi ve Windows ála UAC, které nedovolí zastaralému WinDbg uložit nastavení do Program Files nebo nějakého jiného chráněného místa, kam si natavení chce persistovat.

Není tomu tak.

Windows Debugger totiž má logiku svojí – konkrétní nastavení UI je zabaleno do podoby Workspace (mimo fontu je tam i layout oken a spousta dalších věcí). Workspaces můžeme mít více a můžeme mezi nimi přepínat (mimochodem VS2015 přišlo s layouty, implementováno však příčetněji).

Záludnost je v tom, že výchozí nastavení WinDbg má vypnuté ukládání změn Workspace. Tedy cokoliv nastavíme, tak se vypnutím WinDbg zapomene, aniž by se to na cokoliv zeptalo. Mám dokonce pocit, že toto se v průběhu verzí muselo změnit, protože kdysi se mě WinDbg při ukončování na změnu Workspace ptal.

Jak tedy font změnit, aby si to WinDbg do příště zapamatoval?

  1. Otevřeme WinDbg (neotevíráme žádný dump ani jinou debugging session).
  2. V Menu File zvolíme Save Workspace (změna by se měla uložit do default Workspace).
  3. Vystoupit, nastoupit, font by se měl pamatovat.

Změna se kupodivu projeví i v X64 i X86 verzi WinDbg.

Pokud by to kladlo nějaký odpor

  • Přes View / Options / Worspace Prompts = Always Ask povolíme dotazy na uložení změn Workspace
  • Přes File / Delete Workspaces… můžeme vyházet nežádoucí workspaces (klidně všechny :-))

…mno, jak jednoduché, už nebudu muset s každým spuštěním znovu nastavovat font přiměřený své slepotě, resp. vhodný pro prezentaci.

Visual Studio: Úprava snippetu „ctor“, aby kurzor po rozbalení skončil v místě pro zadávání parametrů

Pokud používáte snippet „ctor“ pro vytváření konstruktorů tříd, může vás štvát, že kurzor po jeho rozbalení skončí připraven v těle konstruktoru a nikoliv v místě pro zadávání parametrů.

ctor1

Drtivá většina constructorů v dnešní době stejně pouze přebírá hodnoty parametrů, které uloží do lokálních privátních fieldů. Často readonly, většinou jako dependencies v patternu Constructor Injection z rodiny Dependency Injection. Takové konstruktory se poměrně efektivně vytvářejí s použitím akce „Introduce and initialize field“ na zapsaném parametru (ať už za použití Resharperu, nebo Introduce and initialize field extension).

expand

Chceme-li změnit pozici kurzoru, stačí upravit snippet ctor a umístit marker $end$ na místo, kde chceme kurzor připravit.

Pokud máme Resharper, dostaneme se na editaci snippetu přes menu Resharper ~ Tools ~ Templates Explorer. Vybereme scope C# a editujeme „ctor“:

public $classname$ ($END$)
  {
	    
  }

Bez Resharperu je potřeba editovat přímo soubor snippetu na disku, najdete ho v cestě C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC#\Snippets\1033\Visual C#\ctor.snippet. Je to krátké XML v kterém příslušný blok rychle najdete.

Výsledné chování je pak mnohem přímočařejší:

full