Eintrag-Details: Teched 2009 Berlin, Tag 2 bis 4
Hier erstmal das Bild des Tages. Sowas passiert, wenn der Rechner am TechNet-Stand während der Party nicht gelockt wird und jemand sich am Hintergrundbild des Desktops zu schaffen macht:

Irgendwas scheint diesem Tux am Recycle Bin nicht zu gefallen...
Aber der Reihe nach. Am Montag (Tag 0) waren fast alle Sessions, inklusive Keynote und General Developer Session reines Marketing Blah-Blah. Ein Highlight war einzig Mark Minasis "12 Tips to secure your Windows Systems revisited...". Nicht weil mir der Inhalt so neu wäre, sondern des Vortragsstils wegen. Minasi ist grossartig, so was wie der Peter Ustinov des IT Business.
Dienstag (Tag 1) war erstmal Scott Cates "Visual Studio Tips an Tricks" angesagt. Sehr cool. Dann die Bitlocker Session. Das ist sehr coole Technologie, definitiv besser als SRPs. In der Mittagspause dann "Face-Lifting MFC Applications on Windows 7". Es ging um Neues in VS2010 und MFC für Windows 7. Sehr gelungene Integration, nach allem was ich sehe, aber wie es dabei um die Unterstützung von Downlevel-Platforms bestellt ist - dazu habe ich nur ausweichende Antworten erhalten.
Dienstag abend war auch nur Party, aber schlagartig um 8 war last order. Aber Kai und ich haben das Beste aus der Zeit gemacht...
Zumindest Kai war gut drauf:

Mittwoch war für mich erstmal Windows Identity Foundation Overwiew angesagt. Schon schwer, wenn der Vortragende Italiener ist und Englisch spricht. Später Windows Desktop Optimisation Overview. Sehr coole Demo, DaRT gehoert ab jetzt zum Werkzeugkasten.
Später dann die Session über XP Mode und MedV. Naja, den Hype um XP Mode kann ich nicht mehr so verstehen, SSO geht damit nicht und warum XP Mode nur mit VT geht und MedV den nicht braucht, erschliesst sich wohl niemandem so wirklich. Aber bestimmt hat jeder eine unterschiedliche Sicht auf die Dinge.
Donnerstag (also heute) war erstmal Ausschlafen angesagt, weil keine der ersten Sessions wirklich so interessant war. Dann die Russinovich-Sesssion "Windows 7 and Windows Server 2008 R2 Kernel Changes". Ich sitze im Auditorium und unterhalte mich vor der Session mit Kai, dreht sich der Typ in der Reihe vor mir um und fragt mich: "Ich glaube wir kennen uns?". Das war Jochen Kalmbach, den ich als MVP aus der deutschen VC Newsgroup kenne. Hätte ich nicht Mitte 2000 bei der Homag gekündigt, etwa da wo er bei der Homag-Tochter Holzma angeheuert hat, wären wir sogar Kollegen gewesen. So habe ich Jochen heute endlich mal in Kohlenstoff-Form kennengelernt, was mich extrem gefreut hat, und was dem Russinovich-Vortrag neben dem anschliessenden Mitagessen mit Jochen und Henning Krause, einem Exchange-Development MVP und gleichzeitig einer sehr sympathischen Erscheinung, das Tüpfelchen auf's i gesetzt hat.
Müssig zu erwähnen, dass heute nach Dienstag zum zweiten Mal Party war, aber nur bis halb 8 abends. Mal sehen, was der morgige Tag noch so vollends bringt.
Teched 2009 Berlin, Tag -1 und 0
(Ein Klick auf die Abbildung startet sie in Normalgröße in einem separaten Browserfenster)
Wunschzettel
Bald ist Weihnachten. Wer mir was schenken will und zuviel Geld übrig hat, soll mir bitte sowas schenken:
(Ein Klick auf die Abbildung startet sie in Normalgröße in einem separaten Browserfenster)
Das ist der HP Superdome aus dem letzten Channel 9 Interview mit Mark Russinovich. 128 Itanium Kerne mit Hyperthreading. Yes, Virginia, there is a Santa Claus, and keep wishing, you know I am.
Source Server und Symbol Server Setup mit Subversion
Mit diesem Blogpost will ich mal mein privates Source- und Symbolserver Setup beschreiben. Einerseits soll mir das helfen, die Umgebung schnell wieder ans Laufen zu bringen, wenn mal was abraucht, andererseits kann es vielleicht anderen helfen, sich eine ähnliche Umgebung aufzubauen.
DISCLAIMER: Das nachfolgend beschriebene Setup ist sicherlich nicht unbedingt der Weisheit letzter Schluss, vielleicht kann man da noch einiges optimieren. Über Verbesserungsvorschläge bin ich da natürlich stets dankbar. Andererseits kann ich mir durchaus vorstellen, dass die beschriebene Vorgehensweise zumindest in kleineren Softwareshops exakt so wie hier beschrieben sehr gut funktionieren kann. Darüberhinaus denke ich, dass das eigentliche Interface zum Source Server so gut abstrahiert ist, dass sich die Informationen aus diesem Blogpost auch sehr leicht auf andere Versionskontrollsysteme übertragen lassen und daher nicht allzu Subversion-spezifisch sind.
Wozu ist das Ganze gut?
Mit einem gut funktionierenden Source Server und Symbol Server Setup zusammen mit einem Versionskontrollsystem kann man folgende Ziele sehr einfach erreichen:
- Automatisiertes Runterladen der Symbole von Microsofts Symbol Server, was einem das Debugging extrem erleichtern kann und zumindest ansonsten die nur als Hexadezimalzahlen sichtbaren Adressen durch Funktionsnamen ersetzt.
- Automatisiertes Laden eigener Symbole in den Debugger mit zugehörigem automatisierten Auschecken des dazu passenden Sourcecodes. Damit ist man in der Lage, Minidumps von Kunden, beispielsweise durch Dr.Watson erzeugt, oder von der Winqual-Website (so man einen Account hierfür hat), in den Debugger zu laden und der Debugger sorgt dann selbständig dafür, dass der zugehörige Sourcecode-Stand ausgecheckt wird. Man landet damit dann direkt in der Sourcecodezeile, wo der Crash stattfand, auch wenn die zugehörigen Quellcodedateien zwischenzeitlich Veränderungen erfahren haben.
Doch zunächst mal einige Begriffsklärungen.
Was ist ein Symbol Server?
Ein Symbol Server ist eine DLL, die es gestattet, Symbole von woanders her in den Debugger zu laden. Mit Visual Studio 2005 und 2008 oder den Debugging Tools for Windows shippt als Symbol Server die Datei symsrv.dll mit - man kann sich aber in der Theorie auch einen anderen Symbol Server selber bauen indem man eine DLL schreibt, die statt symsrv.dll vom Debugger als Symbol Server verwendet wird und beispielsweise Symbole aus einer Datenbank o.ä. extrahiert, wo vorher die Symbole abgelegt wurden. Aber mit der Installation der drei vorgenannten Produkte hat man praktisch schon den Standard Symbol Server von Microsoft und dieser operiert mit sogenannten Symbol Stores. Ein Symbol Store ist nichts anderes als ein Share, auf dem Symbole (also PDB files) und optional Binaries (also .exe oder .dll files, PE files eben) liegen. Diese Dateien werden dort abgelegt, damit man sie sich dann beim Debuggen in den Debugger laden kann und damit Funktionsnamen, lokale Variablen etc. anzeigen lassen kann. Eben all das, was man im Debugger so üblicherweise braucht. Abgelegt werden die Symbole auf dem Symbol Store durch Automatismen, die der Debugger nach entsprechender Konfiguration selber mitbringt, oder durch Ausführen von Tools, beispielsweise im eigenen Buildprozess. Wird beispielsweise der Debugger entsprechend konfiguriert, etwa mit entsprechenden Umgebungsvariablen, so sorgt er beim Debuggen selbständig dafür, dass für die Binaries, die das Betriebssystem mitbringt, die entsprechenden Symbole vom Symbol Store von Microsoft heruntergeladen werden. Wie das geht zeige ich weiter unten. Andererseits kann man sich in einem Symbol Store auch Symbole für die eigenen Binaries ablegen, beispielsweise automatisiert aus dem daily build. Dazu verwendet man das Tool symstore.exe, und wie man das anwendet, zeige ich auch weiter unten.
Was ist ein Source Server?
Ein Source Server ist auch wieder nur eine DLL, in diesem Fall die Datei srcsrv.dll. Sie shippt auch mit den drei vorgenannten Produkten mit. Diese DLL verwendet man unter der Haube, wenn man die Perl-Skripte verwendet, die mit dem Source Server Support der Debugging Tools for Windows mitkommen. Diese Perl-Skripte (man braucht nur jeweils eines, je nachdem, welches Versionskontrollsystem man verwendet) dienen dazu, die beim Build entstandenen PDB files zu indizieren. "Indizieren" bezeichnet hier einen Vorgang, bei dem die PDB files um Informationen bereichert werden, die ein automatisiertes Auschecken des Source Codes aus dem Versionskontrollsystem gestatten. Wenn man sich also ein indiziertes PDB File mal in einem Hexeditor betrachtet, wird man erkennen, dass dort für jede Datei, die zum Builden des zugehörigen Binaries verwendet wurde, die Revisionsinformationen aus dem verwendeten Versionskontrollsystem abgelegt werden, samt Kommandozeile, wie diese Revision aus dem Versionskontrollsystem auszuchecken ist. Die folgende Abbildung zeigt, wie beispielsweise ein von mir indiziertes PDB im Hexeditor auszugsweise ausschaut:
(Ein Klick auf die Abbildung startet sie in Normalgröße in einem separaten Browserfenster)
Deutlich erkennbar ist, dass offenbar eine Environmentvariable SVN_EXTRACT_CMD verwendet wird, die als Wert svn.exe hat (das ist das Kommandozeilentool für Subversion). Dann folgen aufgelistet die Checkout-Kommandos wobei alle hier referenzierten Sourcefiles im Verzeichnis
http://ripley/svn/cvs/trunk/symbtest
auf meinem Subversion-Server ripley liegen. So sieht man beispielsweise an der Zeile
c:\applic\symbtest\symbtest\symbtestview.cpp* http://ripley/*svn/cvs/trunk/symbtest/symbtest/symbtestView.cpp*3863
, dass die lokal beim Builden verwendete Datei c:\applic\symbtest\symbtest\symbtestview.cpp der Datei
http://ripley/svn/cvs/trunk/symbtest/symbtest/symbtestView.cpp
in Revision 3863 entpricht. Nun ist auch klar, dass das Indizieren abhängig ist vom verwendeten Versionskontrollsystem, weil natürlich durch den Indizierungsvorgang je nach Versionskontrollsystem unterschiedliche Auscheckkommandos in das PDB File geschrieben werden müssen. So heisst beispielsweise bei Perforce das Kommandozeilentool zum Auschecken p4.exe, Bei Subversion svn.exe und bei CVS cvs.exe. Mal ganz davon abgesehen, dass natürlich Revisionsinformationen und die Kommandozeile auch jeweils unterschiedlich sind. Von Hause aus unterstützen die Windows Debugging Tools dabei folgende Versionskontrollsysteme (die Namen in Klammern bezeichnen die für das Indizieren verwendeten Batchfiles, die mit den Windows Debugging Tools ausgeliefert werden):
- Visual Source Safe (vssindex.cmd)
- Team Foundation Server (tfsindex.cmd)
- Subversion (svnindex.cmd)
- Perforce (p4index.cmd)
- CVS (cvsindex.cmd)
Doch wie man das Indizieren vornimmt, dazu lasse ich mich weiter unten aus, zunächst beschreibe ich, welche Software man braucht, und wie man seine Environmentvariablen und Symbol Stores clever anlegt.
Erforderliche Software
Zunächst braucht man mal eine aktuelle Version des Microsoft Debugging Toolkits für Windows, wovon man einfach eine Standardinstallation vornimmt, bei mir landet die in "c:\Program Files\Debugging Tools for Windows (x86)". Als nächstes benötigt man zum Indizieren eine Perl-Installation. Ich verwende hier ActivePerl von ActiveState. Auch hiervon macht man eine Standardinstallation, die landet bei mir im Verzeichnis c:\perl. Als drittes braucht man im Fall von Subversion noch einen SVN-Kommandozeilenclient. Ich verwende hier den CollabNet Subversion Client. Auch von dem macht man eine Standardinstallation, die landet bei mir in "c:\Program Files\CollabNet Subversion". Der Einfachheit halber ergänze ich auch noch folgendes zur Umgebunbgsvariable PATH:
C:\Perl\site\bin;C:\Perl\bin; C:\Program Files\CollabNet Subversion; c:\srcsrv; c:\Program Files\Debugging Tools for Windows (x86)
Was soll der Pfad c:\srcsrv? Dieses Verzeichnis lege ich mir an und kopiere da den kompletten Inhalt von "c:\Program Files\Debugging Tools for Windows (x86)\srcsrv" rein. Das mache ich, weil ich an den Dateien srcsrv.ini und svn.pm (dem Perl-Modul für Subversion) einige Änderungen machen muss und ich beim nächsten Update der Debugging Tools diese Änderungen nicht verlieren will. So ändere ich in c:\srcsrv.ini die Zeile
MYSERVER=mymachine.sys-mygroup.corp.microsoft.com:1666
ab in
MYSERVER=http://ripley/svn/cvs
und ergänze in der Section [trusted commands] eine Zeile mit dem Inhalt
svn.exe
Erstere Änderung spezifiziert natürlich den Pfad zu meinem SVN-Repository, die zweitere Änderung verhindert, dass der Debugger beim Auschecken ständig mit der Warnung nervt, dass er jetzt ein potentiell gefährliches externes Programm ausführt. Die solchermassen abgeänderte Datei c:\srcsrv.ini kopiere ich nun auch noch in meine Installation von VS2005 und VS2008. Diese liegen bei mir unter c:\msvc8 und c:\msvc9 und dieses ini-Datei landet dann in den Verzeichnissen c:\msvc8\Common7\IDE und c:\msvc9\Common7\IDE. Zusätzlich sollte man sich bei der Gelegenheit auch noch - wenn man VS2005 einsetzt - die Datei srcsrv.dll in c:\msvc8\Common7\IDE durch die aus "c:\Program Files\Debugging Tools for Windows (x86)\srcsrv" ersetzen, weil die mit VS2005 ausgelieferte Variante nicht so richtig gut funktioniert.
Die zweite Änderung erfolgt in c:\srcsrv\svn.pm wo ich die Zeile 283
"SVN_EXTRACT_CMD=cmd /c svn.exe cat ".
einfach ersetze durch
"SVN_EXTRACT_CMD=svn.exe cat ".
Das ist aber nur eine Schönheitskorrektur, die dafür sorgt, dass nicht noch für jeden Aufruf von svn.exe eine cmd.exe-Hülle gestartet wird.
Aufsetzen der Symbol Stores
Um einen Symbol Store aufzusetzen, braucht man eigentlich nur eine Maschine mit einer halbwegs grossen Festplatte, in meinem Fall heisst diese Maschine LaForge. Mein Ziel war es, zwei Symbol Stores auf LaForge zu haben, wobei einer die Symbole von Microsoft speichert (websymbols) und der zweite die Symbole, die ich selber generiere als Teil meines Builds (privatesymbols). Dieser zweite Store ist auch das, was man regelmässig backuppen sollte, damit man im Fall eines Plattencrashes die eigenen Symbole wiederherstellen kann. Also lege ich zwei Shares an auf LaForge und zwar:
\\laforge\websymbols
und
\\laforge\privatesymbols
Als Berechtigungen vergebe ich NTFS-seitig Vollzugriff für Everyone und Share-seitig Leseberechtigung für Everyone und Vollzugriff für "Authenticated Users". Natürlich kann man das beliebig paranoid gestalten, der Fantasie sind da keine Grenzen gesetzt. Dass Authenticated Users hier Schreibrechte haben sollen, garantiert mir, dass auch unprivilegierte User automatisch hier die von Microsoft geladenen Symbole speichern dürfen, sodass sie alle Rechner in meinem LAN auch von dort laden können und nicht jedesmal auf den Microsoftschen Symbol-Store gehen müssen. Und meine User sind alles LUA Users, also hat das schon seinen Sinn.
Damit die Symbole auch lokal erstmal gecached werden und vom Debugger geladen werden können fehlen jetzt noch drei Dinge:
- Ich lege auf jeder Entwicklungsmaschine die Verzeichnisse c:\websymbols und c:\privatesymbols an.
Ich lege auf jeder Entwicklungsmaschine die Umgebungsvariable _NT_SYMBOL_PATH mit folgendem Wert an:
srv*c:\websymbols*\\laforge\websymbols* http://msdl.microsoft.com/download/symbols; srv*c:\privatesymbols*\\laforge\privatesymbols*
Eintragen von
c:\websymbols*\\laforge\websymbols* http://msdl.microsoft.com/download/symbols
undc:\privatesymbols*\\laforge\privatesymbols*
als "Symbol file (.pdb) locations in VS2005/2008 in den "Debugging" - "Symbols" Options, die man über die Menüpunkte "Tools"-"Options" erreicht (siehe nächste Abbildung).

(Ein Klick auf die Abbildung startet sie in Normalgröße in einem separaten Browserfenster)
Damit werden dann neue Symbole von Microsoft von http://msdl.microsoft.com/download/symbols geladen und erstmal auf \\laforge\websymbols und dann im lokalen Cache c:\websymbols abgelegt. Die Suchreihenfolge für den Debugger ist dann c:\websymbols - \\laforge\websymbols - http://msdl.microsoft.com/download/symbols, er nimmt also den schnellsten Zugriff, den er bekommen kann. Gleichzeitig werden private Symbole versucht, von c:\privatesymbols geladen, und wenn sie dort nicht gefunden werden, von \\laforge\privatesymbols und dann in c:\privatesymbols gecached.
Indizieren privater Symbole und Ablegen im privaten Symbol Store
Nachdem nun die Infrastruktur steht, können wir jetzt mal unser Lieblingsprodukt builden, indizieren und auf dem eigenen Symbolstore ablegen. Dazu mache ich im Buildverzeichnis des Produkts (also da wo die EXE- und DLL-Files sowie die zugehoerigen PDB files stehen) eine Konsole (cmd.exe) auf und gebe in etwa folgendes ein:
svnindex.cmd /debug /source=<Pfad1>;<Pfad2>
Dabei stellen <Pfad1> und <Pfad2> Verzeichnisse daher, unterhalb von denen nach Sourcefiles gesucht wird, die zum Builden der Binaries verwendet wurden. Wenn man lieber das Verzeichnis angibt, unter dem nach zu indizierenden PDB files gesucht werden soll, dann tut man das mit dem /symbols=<Pfad> Parameter. Der Parameter /debug sorgt lediglich für verbose output.
Hat man so nun seine PDB files indiziert, liegen sie natürlich immer noch auf der Maschine, auf der gerade gebuildet und indiziert wurde, aber noch nicht auf dem symbol store. Auf diesen bringt man nun die pdb und exe/dll Files mit folgendem Kommando:
symstore add /r /f <Pfad>\*.* /s \\laforge\privatesymbols /t <Projektname> /v <versionsnummer> /compress
Dabei ist <Pfad> das Verzeichnis unter dem rekursiv (/r) nach PDB Files gesucht werden soll, die dann in den Symbolstore \\laforge\privatesymbols kopiert werden. Mit /t kann man nun noch so etwas wie einen Produktnamen und mit /v eine Versionsnummer angeben. Wozu letzte beideren gut sind, weiss ich selber nicht, jedenfalls tauchen sie aber in den Logfiles auf dem Symbol Store wieder auf. Mit /compress werden die Dateien im Symbol Store noch LZ-komprimiert abgelegt und der \*.* hinter /f <Pfad> sorgt dafür, dass nicht nur die PDB files, sondern auch die EXE und DLL files auf dem Symbol Store landen. Will man letzteres nicht, so gibt man eben /f <Pfad>\*.pdb an. Was fuer einen Vorteil es hat, die PE files auch noch mit auf dem Symbol Store abzulegen, hat sich mir noch nicht so ganz erschlossen, aber da LaForge eine mördergroße Festplatte hat, mache ich mir da keinen Kopf drum und speichere einfach alles ab.
Konfigurieren von VS2005/VS2008
Nun muss eigentlich nur noch VS2005/2008 so konfiguriert werden, dass es mit einem Source Server arbeitet. Dazu wählt man aus dem Menü "Tools"-"Options" an und wählt dann in dem nun erscheinenden Dialog im Baum links den Punkt "Debugging" an und setzt das Häkchen bei "Enable source server support" und optional "Print source server diagnostic messages to the output window", wie in der nächsten Abbildung:

(Ein Klick auf die Abbildung startet sie in Normalgröße in einem separaten Browserfenster)
Bonustrack 1: JIT Debugging mit Windbg und Symbol Server Anbindung
Will man aus irgendeinem Grund lieber Windbg zum Debuggen nehmen, beispielsweise auf Maschinen von Testern, die ansonsten keine full-blown Installation von Visual Studio haben oder wenn man dafür keine Lizenz verschwenden möchte, dann kann man sich auch Windbg so konfigurieren, dass man damit die Annehmlichkeiten des automatisierten Auscheckens bekommt. Dazu konfiguriert man sich die Umgebungsvariable _NT_SOURCE_PATH und weist ihr den Wert SRV*;SRV*\\laforge\privatesymbols zu. Nun kann auch Windbg automatisch die privaten PDB files ermitteln und die zugehörigen Auscheckkommandos durchführen. Allerdings checkt es dann in ein Unterverzeichnis src im Windbg Installationsverzeichnis aus, was natürlich keine gute Sache für LUA User ist. Daher reserviert man sich am Besten ein Verzeichnis auf der Entwickler- oder Testermaschine, in die Windbg auschecken darf. Bei mir ist das das Verzeichnis c:\srccache, dem ich einen entsprechend relaxten Security-Descriptor verbrate, so dass unprivilegierte User auch da hinein auschecken duerfen, wenn sie Windbg verwenden. Was dann noch fehlt ist das Definieren einer weiteren Umgebungsvariablen namens DBGHELP_HOMEDIR, der ich dann den Wert c:\srccache zuweise. Um nun Windbg als JIT Debugger einzurichten, muss man nun nur einmal als privilegierter Benutzer windbg mit dem Kommandozeilenparameter -I aufrufen. Sollte man aber bereits VS2005 oder VS2008 auf seiner Maschine installiert haben und will später wieder zurück zum Debuggerselektor als JIT Debugger, tut man gut daran, vorher den Value "Debugger" unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug umzubenennen, sonst wird der durch windbg -I geplättet.
Bonustrack 2: Geht das ganze auch mit PDB Files, die mit älteren Versionen von VS erstellt wurden?
Mit PDB Files, die von VS6 (aka VC98) erzeugt wurden, ging die Sache bei mir in einem kleineren Test schon, also denke ich mal, dass das schon generell gehen sollte.
Das wär's also zum Thema Source Server und Symbol Server. Keep debugging, you know, I am.
Visual Studio 2005 und das Windows 7 SDK
Link: http://support.microsoft.com/default.aspx/kb/949009
Wer mit Visual Studio 2005 auf das Windows 7 SDK einfach mal so unbedarft umsteigt wie ich, wird sich schnell wundern, warum der Linker bei vielen Importbibliotheken des neuen SDKs mit Meldungen wie
uuid.lib(ieguids.obj) : fatal error LNK1103: debugging information corrupt; recompile module ADSIid.Lib(guid.obj) : fatal error LNK1103: debugging information corrupt; recompile module
die Grätsche macht. Der Grund ist, dass diese Bibliotheken mit dem Compiler von Visual Studio 2008 erstellt wurden, und um die zu Linken, benötigt man einen Hotfix für Visual Studio 2005 SP1:
http://support.microsoft.com/default.aspx/kb/949009.
Natürlich wird der Hotfix, für x86 gerade mal schlappe 18 MByte gross, genauso wie das SP1 als selbstentpackendes Executable um ein MSP-File ausgeliefert, das Stunden zur Installation bei 100%-CPU-Auslastung benötigt. Seufz...