Debugging en Tracing met Visual Basic.NET André Obelink, MCSD Visual Basic Groep
Me.About Me.VBG - een van de oprichters 1995, eindredacteur, website Me.Experience - VIC20, Commodore 64, Clipper CBM basic vanaf Visual Basic 1.0 Visual Basic.NET 2003/ Rich Clients, Componenten, N-Tier, API’s, Databases Me.Write() - Visual Basic Magazine, Microsoft.NET Magazine Me.CurrentJob -...
Visual Studio.NET debugger Alle.NET talen - Visual Basic.NET, C#, … Native Win32 talen - Visual Basic 5.0, Visual Basic 6.0, C++, … Transact-SQL - SQL Server 7.0, SQL Server 2000, … Alle ASP.NET talen Alle ASP talen - VBScript, Jscript, …
Verschillende typen fouten Syntax Errors - compiler kan code niet compileren - relatief makkelijk op te lossen, de VS.NET IDE biedt je hulp - voorbeeld: typefouten, parameters vergeten etc. Runtime Errors - code is gecompileerd - met debugging goed te traceren - te voorkomen door defensief te programmeren en exceptionhandling - bijvoorbeeld: delen door 0, netwerkverbinding niet aanwezig etc. Logical Errors - alles ‘lijkt’ goed te gaan…. - meest lastige fouten om op te sporen en op te lossen - bijvoorbeeld: berekeningen kloppen niet, onjuiste data in database
Edit & Continue in VB.NET 2003 Geen ‘Edit & Continue’ meer aanwezig - heeft te maken met het feit dat we werken met gecompileerde code - goede nieuws: vanaf Visual Studio 2005 is het weer beschikbaar Waarom ‘Edit & Continue’ niet moet terugkeren… - Informality het spanningsveld tussen debuggen en testen - Trial and Error oplossen zonder werkelijk begrip van de fout - Er worden makkelijker nieuwe bugs geïntroduceerd. - inherent aan ad-hoc aanpassingen - tijdens een sessie meerdere fouten oplossen verhoogt risico nieuwe bugs - aanpassingen aan kleine codeblokken verhoogt risico nieuwe bugs
Configuration Manager Configuration = Debug Symbolbestand (*.pdb) Buildconfiguraties bestaan op 2 niveaus ProjectSolution
Breakpoints Veel gebruikte manier om debuggen te initiëren Flexibeler met condities, hitcount etc. Breakpoints worden opgeslagen bij project Breakpoint-window breakpoint tijdelijk uitzetten
Demo Breakpoints
Debug windows Output-window Locals-, Autos- en Watch-window - alleen de scope is anders - je kunt vanuit deze windows waarden muteren Command- en Immediate-window - hetzelfde window, het kan echter in Immediate-mode draaien - Command-window zoals naam zegt: commando’s uitvoeren - Immediate-window opvragen variabelen, aanroepen procedure Andere windows - Call Stack-window- Me-window - Threads-window- Module-window - Register-window- Memory-window
Demo Debug Windows
Debug en Trace classes Classes met dezelfde met properties en methods - Trace ook geschikt voor gecompileerde applicaties in het veld Het zijn ‘Shared’ classes soort public object Debug methods alleen aangeroepen wanneer DEBUG is aangegeven Trace methods alleen aangeroepen wanneer TRACE is aangegeven Zowel voor VB.NET als C# geldt: Release-builds standaard TRACE = True
Tracing code Write() en WriteLine() informatie wegschrijven - de informatie wordt naar elke TraceListener gestuurd WriteIf() en WriteLineIf() hiermee heb je invloed op het wel/niet loggen van de informatie - je eigen condities, zoals : x>y, intKlantNr = 100 etc. - BooleanSwitch, TraceSwitch Fail() en Assert() Assert indien conditie: False Bovenstaande methods accepteren een geformateerde string: (message, category) - helaas zijn dit ‘sealed’ classes, daardoor niet snel te verhelpen
Trace – opmaak informatie Trace en Debug classes kennen properties en methods waarmee je de formattering kan beïnvloeden IndentSize - het aantal spaties dat ingesprongen moet worden IndentLevel - past de inspringing aan voor de huidige WriteLine() of WriteLineIf() Indent() en Unindent() methods wijzigen ook de IndentLevel
Trace class Write() en WriteLine() kent twee parameters 1. Message – de tekst die je wilt loggen 2. Category – de categorie van de melding De informatie wordt als volgt geformateerd: - : De informatie wordt als volgt geformateerd: - : Trace.WriteLine(“Eerste niveau”, “info”) Trace.Indent() Trace.WriteLine(“Tweede niveau”) Trace.Unindent() Trace.WriteLine(“Eerste niveau”, “info”) info: Eerste niveau Tweede niveau info: Eerste niveau
Trace Listeners ‘Alle’ gelogde data wordt doorgeven aan ‘alle’ trace listeners binnen het Application Domain - meestal geconfigureerd door het Config-bestand - je kunt ook ‘at runtime’ classes toevoegen aan de collectie Elke Application Domain creëert haar eigen TraceListners collectie Trace Listeners zijn afgeleidt van de TraceListeners class dus ‘zelfbouw’ mogelijk!
Trace Listeners ClassOmschrijving DefaultTraceListener (standaard aanwezig) Trace berichten worden weggeschreven naar naar OutputDebugString en naar de geattachde debugger (VS.IDE). EventLogTraceListener Trace berichten worden weggeschreven naar het aangegeven EventLog. TextWriterTraceListener Trace berichten worden weggeschreven naar het aangegeven Tekstbestand (Stream) MijnTraceListener Trace berichten worden weggeschreven naar een SQL-Server of Accessbestand of …
Demo Debug en Trace classes
BooleanSwitch en TraceSwitch Invloed op welke data er gelogd wordt BooleanSwitch True/False Aan/Uit TraceSwitch 5 niveaus – ‘cumulatief’ - Off (0)Geen Trace - Error(1)Summiere foutmeldingen - Warning (2)‘Error’ + waarschuwingen - Info(3)‘Warning’ + andere korte boodschappen - Verbose(4)‘Info’ + gedetailleerde boodschappen Ook in te stellen in Application Config bestand Jij moet zelf waarden checken! WriteLineIf()
Switches in Application Config
Voorbeelden gebruik Switches Dim objBlnSwitch As New BooleanSwitch("MijnBooleanSwitch", "") Dim objBlnSwitch As New BooleanSwitch("MijnBooleanSwitch", "") Dim objTrcSwitch As New TraceSwitch("MijnTraceSwitch","") Dim objTrcSwitch As New TraceSwitch("MijnTraceSwitch","") ' Value = 1 --> Wel loggen ' Value = 1 --> Wel loggen Trace.WriteLineIf(objBlnSwitch.Enabled = True, "Boolean") Trace.WriteLineIf(objBlnSwitch.Enabled = True, "Boolean") ' Value = 3, Error = 1, 1 Wel loggen ' Value = 3, Error = 1, 1 Wel loggen Trace.WriteLineIf(objTrcSwitch.TraceError = True, "Error") Trace.WriteLineIf(objTrcSwitch.TraceError = True, "Error") ' Value = 3, Verbose = 1, 4 niet Niet loggen ' Value = 3, Verbose = 1, 4 niet Niet loggen Trace.WriteLineIf(objTrcSwitch.TraceVerbose = True, "Verbose")
Dynamische TraceListener <add name="MijnLog" <add name="MijnLog" type="System.Diagnostics.TextWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\MijnLog.log" /> initializeData="c:\MijnLog.log" />
Demo Dynamische TraceListener
Debug SQL-Server Stored Procs Min. SQL Server 7.0, SQL Server 2000 aanbevolen Database ‘server’ min. Windows NT 4.0 MSDE2000 kan men debuggen met VS.NET Pro > Voor ‘echte’ SQL2000 VS.NET Ent. of Architect Installeer SDI (niet stan- daard).
Probleemoplossing debug SQL Sqlle.dll + Sqldbreg2.exe op debug werkstation Sqldbg.dll op server + debug werkstation + registr. Mssdi98.dll in \binn map van SQL Server - SQLServer2000 installatie VS.NET juiste versie op juiste locatie - MSDE2000 installatie VS.NET Pro juiste versie op onjuiste locatie Rechten op sp_sdidebug stored procedure - hangt af van gebruikte accounts (service + programma) - EXEC master..sp_sdidebug WinXP SP2 niet debuggen in eigen applicatie - debuggen vanuit Server Explorer – Step Into gaat ‘goed’… - op aanvraag hotfix bij Microsoft beschikbaar
Debuggen SQL-Server Server Explorer – Stored Proc – Step Into SP Breakpoint moet wel in Stored Procedure zelf staan en kan niet in aanroepende functie Binnen code-windows ook ‘Run Selection’
Demo SQL Server debugging
Samenvattend Tracing is een geweldige tool, omdat… - je inzicht kunt krijgen in lastige, logische problemen… - je flexibel bent in het wel/niet tracen, welk niveau, welke opslagmedia - je van buitenaf het trace-gedrag kan beïnvloeden (App.Config) Tracing is een geweldige tool, maar… - klant moet niet de indruk krijgen dat je programma vol bugs zit… - proberen te vermijden om veel te tracen naar EventLog (traag) - elke WriteLineIf() is een check in je programma (performance) - Trace.Assert staat is ‘enabled’ in standaard Release Builds - *.pdb bestanden nodig, maar beïnvloeden performance nadelig
Meer informatie Comprehensive VB.NET debugging Mark Pierce - A!Press Microsoft.NET Magazine #7 Debugging en Tracing met Visual Basic.NET André Obelink, VBG (december 2004)
© 2004 André Obelink – een samenwerking tussen
Conditional Compilation #Const Debug = False' Debugging uit #Const Trace = True ' Tracing aan Class VerkoopOrder Public Sub Save() #If Debug Then In dit geval nooit bij Trace ControleerRegelsMetKop() ControleerRegelsMetKop() #If Trace Then SchrijfNaarLog(“Test 1,2,3”) SchrijfNaarLog(“Test 1,2,3”) #End If VerkoopOrderOpslaan() VerkoopOrderOpslaan() End Sub End Sub End Class
Trace Listeners - Constructor De InitializeData attribuut wordt aangegeven in de constructor van de TraceListener New() - DefaultTraceListener, geen parameters - EventLogTraceListener, de naam van het EventLog - TextWriterTraceListener, de naam van het tekstbestand of de stream