Advanced DebuggingF9 ist nicht genug
Ingo [email protected]
Ingo Rammer und
• Kleine Beratungsfirma für Softwareentwickler
• Unterstützung, Coaching und Beratung für Software-Architekten und -Entwickler– Architektur- und Code-Reviews– Prototypentwicklung und Architekturberatung– Coaching und Mentoring– Anwendungsoptimierung und Troubleshooting
• http://www.thinktecture.com• [email protected]
Agenda
• Debugging von Applikationen mit Visual Studio– Erweiterte Breakpoints, Tracepoints, ...– Makros– Debugger-Attribute– Visualizer für eigene Typen– Visualizer für fremde Typen
• Vorbereitung von Anwendungen für Debugging– Exception-Handling– MDbg– Eigene Debugger mit dem Objektmodell von MDbg– Lock-Bearbeitung– Automatische Erstellung von Memory-Dumps
• Heute Nachmittag: Production Debugging („was mach ich bloss mit dem Memory-Dump?“)
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 3
Teil 1
F9 ist nicht genugDas kann Visual Studio
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 4
Erweiterte Breakpoints
• Breakpoints– „Just My Code“ (ToolsOptionsDebuggingGeneral)– CTRL+B, Breakpoint Groups
• Tracepoints• Hitcount• Conditions• Makros• Command Window
– help– alias
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 5
Interaktive Tests
• Interaktive Klassenerstellung– Aufruf von statischen Methoden
• Object Workbench– Aufruf von Instanzmethoden
• Immediate Fenster
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 6
DebuggerDisplay
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 8
public class Invoice{ [DebuggerDisplay("Items: {_items.Count} Sum: {Sum}")] private List<InvoiceItem> _items = new List<InvoiceItem>();
public double Sum { get { double sum = 0; foreach (InvoiceItem itm in _items) sum += (itm.Price * itm.Amount); return sum; } }}
• [DebuggerDisplay]-Attribut
DebuggerVisualizer
• [DebuggerVisualizer] Attribut• Klassen müssen [Serializable] sein
– Visualizer erhält serialisierten Klon– Rückmeldung per objectService.ReplaceObject()
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 9
[DebuggerVisualizer(typeof(MyVisualizer))][Serializable]public class Invoice{ //...}
Debugger Visualizer
• Für Applikationsklassen (Visualizer in gleicher Assembly wie Anwendung)– Referenz auf Microsoft.VisualStudio.DebuggerVisualizers– Ableiten von DialogDebuggerVisualizer
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 10
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider){ MyClass dt = (MyClass) objectProvider.GetObject();
Form1 frm = new Form1(); // ... show data ... windowService.ShowDialog(frm);}
Debugger Visualizer
• Möglichkeit 2: Getrennte Visualizer in Klassenbibliothek
• Visualizer kann global oder per User installiert werden:– Program Files\Microsoft Visual Studio 8\Common7\
Packages\Debugger\Visualizers– My Documents\Visual Studio 2005\Visualizers
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 11
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(InvoiceVisualizer),typeof(VisualizerObjectSource),Target = typeof(Invoice),Description = "Invoice Visualizer")]
Obskures: Debugger Proxy
• Stellvertreter-Klassen im Debugger• Werden automatisch statt den ursprünglichen
Klassen angezeigt
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 12
[assembly: DebuggerTypeProxy(typeof(InvoiceProxy), Target = typeof(Invoice))]
public class InvoiceProxy: Invoice{ private Invoice _val;
public InvoiceProxy(Invoice val) {
_val = val; } ...
Teil 2Vorbereiten für´s Debuggen
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 13
Vorbereitungen?
• Wofür?– Zeitersparnis während Entwicklung– Unterstützung im Testbetrieb („Friendly Customers“)– Fehlersuche im Echtbetrieb („Production Debugging“)
• Grundsätzlich– Während der Entwicklungszeit bestimmen Sie die
notwendige Zeit für späteres Debugging
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 14
Exceptions
• Primärer Einsprungpunkt für späteres Debuggen• Drei Grundregeln
– Auslösen von nicht-essentiellen Exceptions vermeiden (TryParse, File.Exists)
– Was ist essentiell? Wenn die Methode nicht das macht (oder: machen kann), was der Name nahelegt, dann wird eine Exception geworfen
– Exceptions werden nur dort gefangen, wo die Applikation etwas mit der Exception machen kann
• Logging ist kein Grund für re-throws! (Callstack gibt‘s auch später noch)
• Wo muss gecatcht werden?– Threadprozeduren, Finalizer, eventuell Events
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 15
MDbg
• Kleiner, feiner Debugger• Zwei Versionen:
– MDbg SDK (hier nicht relevant)– MDbg Sample (mit Sourcecode)
• Bietet komplettes Debugger Objektmodell
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 16
Beispiel: Locks
• Zu lange Locking-Dauer ist ein Problem für Skalierbarkeit von Applikationen
• Was kann man im Debugger machen?
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 17
MemoryDumps – Ultimative Fehlersuche
• Speicherabbilder sind die ultimative Unterstützung zur Fehlersuche
• Zeigen den Status einer Applikation zu einem bestimmten Zeitpunkt
• Zwei Ausprägungen – Minidump: praktisch nur Callstack, wenige KB gross– Minidump mit „allen Optionen“: komplettes
Speicherabbild, kann einige 100 MB gross werden
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 18
Programmgesteuerte Dump-Erstellung
• DbgEng.DLL (aus „Debugging Tools for Windows“)• Darf in Ihre Programme integriert werden
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 19
[DllImport("DbgHelp.dll", SetLastError = true)]private static extern bool MiniDumpWriteDump( IntPtr hProcess, int processId, IntPtr fileHandle, int dumpType, IntPtr excepInfo, IntPtr userInfo, IntPtr extInfo);
FileStream stream = File.Create(@"C:\test.dmp");Process proc = Process.GetProcessById(pid);int dumpType = (int)0x00000006; // all options// int dumpType = (int)0x00000000; // minidumpMiniDumpWriteDump(proc.Handle, proc.Id, stream.Handle, dumpType, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
Summary
• Debugging von Applikationen mit Visual Studio– Erweiterte Breakpoints, Tracepoints, Makros– [DebuggerDisplay], [DebuggerVisualizer],
[DebuggerProxy]• Vorbereitung von Anwendungen
– Exception-Handling– MDbg– Eigene Debugger mit dem Objektmodell von MDbg
• Beispiel: Lock-Bearbeitung– Automatische Erstellung von Memory-Dumps
• Heute Nachmittag: Production Debugging („was mach ich bloss mit dem Memory-Dump?“)
Dieser Vortrag steht zum Download bereit unter www.prioconference.de 20
http://www.thinktecture.com/
[email protected]://blogs.thinktecture.com/ingo/
In-depth support and consulting for
software architects and developers
{ }