VS-Tipps & Tricks: Insert Tracepoint, der nette Helfer beim Debuggen

Breakpoints kennt jeder, aber Tracepoints!?!

Den Menüpunkt Insert Tracepoint findet man im Kontext Menü des Editors.
Wer kennt das nicht? Man ist mitten in einer Debug-Session, aber man müsste jetzt eine Variable beobachten, wie sie sich entwickelt. Manchmal ist es einfach ungünstig einen Breakpoint zu stetzen, weil der Timing, Focus und manches andere ändert. Zudem, Breakpoints sind lahm und die F5-Taste will man auch icht kaputt machen. Ein TRACE Statement wäre super. Aber jetzt den Code ändern? Evtl. klappt das Edit&Continue nicht oder man kann es nicht einrichten, weil man eine Release Version debuggt.

Hier ist ein Tracepoint ideal. Er leistet das, was ein TRACE Statement auch leistet, nur ohne Code Änderung. Einfach Insert Tracepoint auswählen und angeben was man gerne sehen möchte.
z.B.: $FUNCTION bReset={bResetClipRegion} bEmpty={bEmptyClipRect}

Es stehen einige Makros zur Verfügung, die direkt im Dialog erklärt werden. Gigantisch nützlich sind die Variablen $FUNCTION , $CALLER, und $CALLSTACK. Das geht auch mit Variablen, die sich im aktuellen Kontext befinden, wie in meinem Beispiel zu sehen. Einfach die Variablen in geschweifte Klammern setzten und das war es schon.

Die Ausgabe erfolgt umgehend in der Debug-Ausgabe:
RedirectEraseBkgndToParent(CWnd *, CDC *) bReset=true bEmpty=true
RedirectEraseBkgndToParent(CWnd *, CDC *) bReset=true bEmpty=true
RedirectEraseBkgndToParent(CWnd *, CDC *) bReset=true bEmpty=true

Absolut super ist, dass man dazu noch nicht mal einen Breakpoint setzen muss. D.h. man kann während der Laufzeit einfach so einen Tracepoint setzen ohne große Eingriffe in die Software.

Und ganz ohne Probleme lässt sich auch ein Breakpoint in einen Tracepoint umwandeln und umgekehrt. Bei den Eigenschaften eines Breakpoints im Kontextmenü kann man die Eigenschaft When hit… entsprechend bearbeiten. Nimmt man den Haken bei Continue Execution heraus, dann hat man einen normalen Breakpoint. Setzt man den Haken bei Continue Execution, so macht man aus einem Breakpoint einen Tracepoint, man muss nur noch eine entsprechende Nachricht nach Wunsch angeben, die in der Debug Ausgabe angezeigt werden soll.

❗ Beachten muss man jedoch, dass die Performance schlechter ist als bei einem eingebauten TRACE. Denn ein Breakpoint wird ausgelöst und der Debugger übernimmt kurzfristig die Kontrolle.

VS-Tipps & Tricks: Edit.GotoBrace (Strg+´) kann noch mehr

Mit Strg+´ kann man ja bekannterweise die nächste passende schließende bzw. geöffnete Klammer finden. Mit Umschalt+Strg+´ kann man diesen Bereich auch direkt markieren. Diese Funktion ist nicht unbedingt eine Neuigkeit.

Viele wissen jedoch nicht, dass man auch passende #if, #ifdef, #ifndef, #else, #elif, #endif Direktiven damit anspringen kann. Man muss dazu das Caret einfach nur auf die entsprechende Direktive platzieren und mit Strg+´ springt man zum nächsten #else, #endif oder wieder an den Kopf des ersten #if Blockes.

Auch in diesem Fall kann man auf einfache Weise mit Umschalt+Strg+´ den entsprechenden Codeblock markieren.

„Elevated“ Programme unter Vista / Windows 7 / Windows 8 / Windows 10 haben auf einmal keine gemappten Laufwerke mehr

Ist man Administrator unter Vista, Windows 7, Windows 8 oder Windows 10 und UAC ist aktiviert, dann existieren technisch zwei Sicherheits -Tokens. Ein Token mit den vollen Administrativen Rechten und ein reduziertes gefiltertes Token, ohne Admin-Rechte.

Wenn man sich anmeldet und Netzwerklaufwerke (Freigaben/Shares) zugeordnet werden, dann erfolgen diese Laufwerksmappings in dem Token mit den reduzierten Rechten.

Startet man nun eine Session mit angehobenen, vollen administrativen Rechten, dann sind die vorher zugeordneten Netzwerklaufwerke in dieser Session nicht sichtbar.
Ein etwas ungewöhnliches aber durchaus logisches Verhalten.
Das Logon Skript läuft eben nicht in dem selben Sicherheitskontext, wie Prozesse, die man mit vollen angehobenen Rechten startet. Defakto sind es wirklich zwei verschiedene Logon’s mit zwei verschiedenen Logon-ID’s.

Mit einem einfachen setzen eines Registry Keys kann man jedoch erreichen, dass auch die angehobenen Admin-Sessions die gleichen Laufwerkmappings erhalten:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
EnableLinkedConnections = 1 (DWord)

Aber leider ist dieser Schalter nicht als Standard gesetzt.
Ärgerlich wird dies, wenn man ein kleines Setup-Programm schreiben will, dass einige Daten aus dem Nezwerk kopieren soll und dem man ein entsprechendes requireAdministrator-Manifest gibt. Startet man dieses Programm findet es auf einmal nicht mehr die Laufwerke, die eben noch verfügbar waren. Umgehen kann man das ganze nur in dem man UNC-Dateinamen verwendet.

Beschrieben wird dies auch hier auch in diesem KB Artikel und besonders dieser TechNet Artikel.

9. Award als deutscher MVP für Visual C++

Es ist zwar schon wieder 8 Tage her, seit ich die Email erhalten habe, aber es ist für mich, wie für jeden anderen MVP, immer wieder spannend ob ein MVP-Titel erneuert wird.
Selbstverständlich ist das nicht. Gerade in den letzten beiden Jahren sind viele meiner „alten“ Kollegen als MVPs ausgeschieden.

Dies ist nun mein neunter Award als deutscher C++ MVP. Die Urkunde lässt untypischer Weise zwar noch auf sich warten, aber die Bestätigung habe ich bereits. 🙂

BTW: Wer mich mal persönlich kennen lernen will, der kann mich voraussichtlich in Frankfurt beim großen Launch „Ready for take off“ von Windows Server 2008, SQL Server 2008 und Visual Studio 2008 vom 19.-21. Februar 2008 treffen.

Nachtrag vom 19.10.2007:
MVP Award

Gibt es einen Unterschied zwischen HMODULE und HINSTANCE?

Ja! Wenn man noch Windows 16bit programmiert. 😉

Nein! Wenn es sich um Win32 dreht.

In Kurzfassung:
❗ Seit Win32 ist HMODULE/HINSTANCE nichts anderes als die Ladeadresse des Modules, egal ob es sich hier um eine EXE oder DLL handelt.
HMODULE und HINSTANCE sind austauschbar in jeder Beziehung.

Wer mehr darüber lesen will findet bei The Old New Thing, diesen Artikel der den historischen Aspekt erläutert.

VS-Tipps & Tricks: Die Combobox im Property Fenster des Dialog Editors

Unscheinbar aber sehr effektiv zum Ändern von großen Dialogen ist die Combobox im Eigenschaftsfenster.
In den meisten Fällen steht in dieser Combobox nur der Name des Objektes, das ausgewählt ist und eine weitere Auswahl ist dann oft hier nicht möglich.

Editiert man jedoch einen Dialog, dann kann man mit dieser Combobox, sehr effektiv und schnell Controls gezielt auswählen. Besonders wenn man Controls übereinander legt weil diese ein oder ausgeblendet werden wird es schwierig diese Controls gezielt mit der Maus zu markieren.
Mit der Combobox kein Problem.
Die Reihenfolge in der Combobox ist die alphabetisch sortiert nach den Namen der Control IDs. Auch das erleichtert die Auswahl, wenn man ein Control direkt anhand seiner ID finden will. Hat man den Dialog nicht designed und will ein Control identifizieren, dass durch einen bestimmten Code gesteuert wird, ist das mit dieser Combobox ein Klax.

Auch wenn man die Maus nicht verwenden will kann man mit dieser Combobox schnell navigieren:
Alt+Eingabetaste, wählt das Eigenschaftsfenster, mit 3 x Tab oder 2 x Umschalt+Tab kommt man in die Combobox, die man dann mit den Cursor-Tasten, bzw. Alt+Pfeilrunter bedienen kann. Mit der Escape-Taste kommt man zurück in die Editoroberfläche.

Wie eine Gruppe von Radio-Buttons ein Programm aufhängen können

Auto-Radiobuttons (BS_AUTORADIO) sind als Standard in fast jedem Dialog zu finden. Das diese netten kleinen Buttons ein Programm dazubringen können sich aufzuhängen, ohne das unbedingt eigener Code im Spiel ist, kann man sich kaum vorstellen.
Aber es kann passieren.

Ein Regular in der Gruppe nntp://microsoft.public.de.vc berichtete dieses Problem mehrfach in der Gruppe. Letzten Endes trugen aber alle Ideen und Vorschläge zu keiner Lösung bei.

In einem Thread wurde dann ein Beispielprogramm veröffentlicht, bei dem mit einem simplen Klick auf einen Radiobutton das Programm in einer Endlosschleife gerät und sich aufhängt.

Die Ursache ist trivial. Eine Gruppe von Auto-Radio Buttons war nicht durch ein Control mit dem Stil WS_GROUP abgeschlossen worden. Solch einen Design Fehler im Dialog hat schon jeder mal gemacht und viele werden die folgende Ausgabe im Debug Fenster kennen: „Warning: skipping non-radio button in group.“

In diesem Fall kam nach der Gruppe Radio Buttons ein Tab-Control, dass den Stil WS_EX_CONTROLPARENT hat. Dieser Stil erlaubt es Dialoge und Controls zu schachteln. Gleichfalls führt dieser Stil dazu, das versucht wird die Gruppe von Radio-Buttons in den untergeordneten Feldern weiter zu führen. Leider waren in den entsprechenden Fenstern auch keine Controls mehr mit dem Stil WS_GROUP und irgendwie hat sich die Windows UI-API dann letzten Endes aufgehängt.

Behoben werden konnte dieser Stil einfach;

  • Entweder man führt ein (evtl. sogar unsichtbares) Static Control ein, direkt nach der Gruppe. Static-Controls werden automatisch mit dem WS_GROUP Stil versehen.
  • Oder man änderte die Z-Order, so dass auf die Radio-Button Gruppe ein anderes Control mit WS_GROUP Eigenschaften folgt.
  • Oder eines der Controls im Unterdialog hat den WS_GROUP Stil, was aber oft genug nicht dem eigentlich gewollten Design entspricht, dass sich die Gruppe in den Unterdialog fortsetzt.

Auch so simplen Warnungen in der Debugausgabe wie „Warning: skipping non-radio button in group.“ sollte man gezielt nachgehen. Manchmal haben heftige Probleme trivialste Ursachen ❗

Anmerkung: Das Beispielprogramm ist zwar noch VC6, aber das Problem liegt im Design der geschachtelten Fenster und der nicht abgeschlossenen Radio-Button Gruppe.

Installation von VC6 unter Vista

Es ist ein Anachronismus und ich weiß gar nicht warum ich das hier schreibe. 😉 Aber es gibt doch immer wieder Leute die Visual C++ 6.0 bzw. Visual Studio 6.0 auf Vista installieren wollen.

❗ Grundsätzlich rate ich jedem ab, für Neueintwicklungen VC6 weiterhin zu verwenden.
Dieser Compiler und diese IDE sind überaltert und VC2005 ist ein würdiger und wirklich guter Nachfolger. Was die Änderungen bzgl. Wizards etc. betrifft ist es reine Gewöhnungssache.

Nun aber gib es genug Legacy Code der evtl. einen Bugfix braucht. OK Also wie installiert man dann VC6 auf Vista? Bzw. Geht es überhaupt?
Ja! Es geht.

Wichtig ist, nur, dass man UAC für die Dauer der Installation am Besten komplett abstellt. Es genügt IMHO nicht nur das Setup als Admin zu starten. Das erkennt Vista sowie entsprechend und fordert dazu auf. Also bei mir spielte sich die Installation der Visual Studio 6.0 Enterprise Version in etwa so ab:

  • UAC abschalten (am einfachsten über die System-Steuerung) und den Rechner neu starten.
  • Nun unbedingt einen Account verwenden der lokaler Admin ist (Aber das war jedem klar, oder?)
  • VC6 Installation starten. Die nette  Meldung über bekannte Kompatibilitätsprobleme nehmen wir dankbar zur Kenntnis.
  • Jetzt wird evtl. die VM für Java aktualisiert und neu gestartet (was sonst).
  • Zwischendrin erfolgt noch mal eine Warnung über bekannte Kompatibilitätsprobleme die wir wieder gerne quittieren.
  • Nun dürfen wir wie gewohnt installieren. Man kann sich die Data Access Components übrigends sparen. Meistens sind sowieso schon neuere Versionen auf dem Rechner. Gleiches würde ich mit den SDK Tools machen. Diese alten Tools machen manchmal auch Ärger beim registrieren.
  • Irgendwann kommt manchmal noch eine Frage nach den JIT-Debugger  settings, am Besten auch die nicht verändern.
    Und wie gewohnt erfolgt ein Neustart der Maschine am Ende der Installation.
  • Danach VC6 SP6 installieren und Rechner neu starten (was sonst).
    Für SP5 muss man etwas hexen, aber es geht mit Tricks auch.
  • Danach UAC wieder einschalten, und es erfolgt der nächste Neustart 😉


Anmerkungen

  • Der Standard Pfad zum Anlegen der Projekt sollte natürlich nicht verwendet werden. Der liegt dämlicherweise ja unter C:\Program Files, aber ich gehe auch hier davon aus, dass dies logisch ist…
  • Beim ersten Start des Compilers und einiger Tools kommen wieder Meldungen über Kompatibilitätsprobleme (vcspawn.exe, rc.exe), diese schalten wir für immer aus.
  • Man sollte VC6 übrigends auch nicht nach VC2005 installieren. Andernfalls muss man VC2005 einer Reparaturinstallation unterziehen. Einige der Registrierungen für den Explorer werden sonst überschrieben und arbeiten nicht mehr korrekt. Aber das ist ja bei allen Installationen von mehreren VS Versionen schon so gewesen. Immer nacheinander installieren beginnend mit der ältesten Version!

Danach arbeitet VC6 ohne Murren. Wenn man möchte kann man für VC6 (devenv.exe) sogar manuell ein Vista Manifest geben, indem man die entsprechende devenv.exe.manifest Datei erzeugt. Nach Geschmack setzt man requireAdministrator oder asInvoker. Für bestimmte Fälle beim Debuggen bietet sich hier requireAdministrator an.

VS Tipps & Tricks: Kontextmenü für Refactor Befehle in VA-X ab Build 1557

Die Refactoring Befehle in VA-X sind ja schon länger bekannt und sind wirklich ein prima Feature (Build 1534 seit 09.2006).

Nur war es manchmal etwas trickreich an diese Befehle zu kommen. Meistens habe ich die Maus verwendet und über dem Symbol platziert und gewartet, bis das entsprechende Dropdown Symbol aus VA-X erschien. Intuitiv und schnell war das nicht.

Seit dem Build 1557 (052007) finden sich die Refactoring Befehle direkt als erster Menüpunkt im normalen Kontextmenü und sind damit auch über die Tastatur direkt mit der Kontextmenütaste (oder Umschalt+F10) zu erreichen. Ein Grund mehr sich diese Funktionen wirklich mal anzusehen. Sie sind wirklich einen Tipp wert!
Meine Favoriten im Refactoring Menü sind immer wieder Find References und Rename.

Und für alle die meinen ich habe was vergessen oder übersehen: 😉

  • Es gab zwar seit dem Build 1540 einen entsprechenden Befehl den man einem Hotkey zuordnen konnte, aber allzu viele Hotkeys passen in meinen Kopf auch nicht rein.
  • Ja und man kam an diese Befehle auch über Umschalt+Kontextmenütaste erhalten. Nur ist das komplette VA-X Menü leider etwas unaufgeräumt und groß.

TFS: Alle Jobs des SQL Agents für den TFS laufen nicht

Nach der Installation des TFS war im Event Log alle 10 Minuten der folgende Fehler zu lesen:

Ereignistyp:       Warnung
Ereignisquelle:    SQLSERVERAGENT
Ereigniskategorie: Job Engine
Ereigniskennung:   208
Datum:             12.09.2007
Zeit:              12:00:00
Benutzer:          Nicht zutreffend
Computer:          SVR-02
Beschreibung:
SQL Server Scheduled Job ‚TfsWorkItemTracking Process Identities Job‘ (0x152D401A0604DF4D984F5835301DA43F) – Status: Fehler – Invoked on: 2007-09-12 12:00:00 – Message: Auftragsfehler  Es kann nicht bestimmt werden, ob der Besitzer (‚Domäne\TFSSETUP‘) von Auftrag ‚TfsWorkItemTracking Process Identities Job‘ Serverzugriff aufweist. (Ursache: Die Informationen über Windows NT-Gruppe oder -Benutzer ‚Domäne\TFSSETUP‘ konnten nicht abgerufen werden, Fehlercode 0x5. [SQLSTATE 42000] (Fehler 15404)  Die Anweisung wurde beendet. [SQLSTATE 01000] (Fehler 3621)).

Der selbe Fehler wurde auch für alle anderen TFS Jobs angezeigt, die im SQL-Agent eingetragen wurden.
Ganz verstehen kann ich den Fehler bis heute noch nicht. Nicht wenige kämpfen mit diesem Problem, wenn man im Internet nach dem Fehler sucht. Direkte Lösungen dazu habe ich nicht gefunden.
Warum nicht korrekt geprüft werden kann, ob die entsprechenden Accounts in der Domäne sind oder nicht ist mir ein Rästel. Der Fehlercode 5 heißt: Zugriff verweigert.

Die Jobs wurden im SQL Server unter dem Benutzer Domäne\TFSSETUP eingetragen. Der entsprechende Benutzer TFSSETUP ist korrekt Mitglied der Domäne und auch Administrator auf der lokalen Maschine auf der sowohl TFS als auch MS-SQL Server 2005 läuft. Warum dieser Account genutzt wurde und nicht TFSSERVICE ist mir ein Rätsel.
OK, aber selbst wenn ich TFSSERVICE als Besitzer wähle funktionieren die Jobs nicht.

Nachdem ich die Jobs auf NT-AUTORITÄT\SYSTEM gesetzt habe ging es dann.
Verstehe wer will.

PS: Wer meint, dass es an dem Recht „Anmelden als Dienst“ liegt, der rät falsch. Der Account TFSSERVICE hat dieses Recht und damit hatte ich auch keinen Erfolg. 

PPS: Meine Installation ist gemischt und funktioniert aktuell ohne Probleme:
Windows 2003 R2 Deutsch
SQL Server 2005 Deutsch
TFS in Englisch
Nur als Anmerkung, da ich einem der letzten Kommentare noch die Absicht hatte, die Installation auf Englisch Pur umzustellen.