Team Build 2010: Comment débugger simplement avec l’indexation des sources!

Team Build 2010 résout fort simplement une problématique que l’on a depuis des lustres: comment débugger facilement une release ancienne ou compilée par une chaine d’intégration continue. Ceux qui savent de quoi je parle l’auront déjà compris: avoir les fichiers sources qui correspondent à ce que vous débuggez peut s’avérer être une tâche difficile voire impossible.

La théorie (grosse maille)

Pourquoi? Revenons rapidement sur le mécanisme du debugging (mais alors très rapidement):

  1. Tout commence par l’Exe que vous débuggez, ainsi que les DLL qu’il utilise: c’est le programme qui est exécuté pas à pas par le débuggeur. Seulement, si vous n’avez pas les sources, vous n’aurez qu’une vue code assembleur de votre programme et même si vous avez passé plusieurs années à faire de l’assembleur, ca ne vous donnera pas pour autant le courage de faire avec!
  2. L’utilisateur veut débugger avec les sources qui ont étés utilisées pour compiler le programme. Un type de fichiers existe pour faire le lien entre un fichier binaire (.exe, .dll): c’est le .pdb. Grossièrement le .pdb stocke pour chaque statement de votre langage le fichier source (un .cs par exemple) dans lequel il se trouvait et à quelle ligne.
  3. Lors du debugging, lorsqu’un fichier binaire est chargé, le débuggeur va tenter de trouver le fichier .pdb correspondant (en cherchant d’abord dans le même dossier que le binaire, puis dans tous les chemins d’une variable système).
    S’il y arrive, il pourra alors tenter d’ouvrir les fichiers sources référencés, ceux-ci sont exprimés en absolu, mais si le fichier n’est pas trouvé alors le débuggeur vous demandera de le localiser vous-même.

Dans ce qui vient d’être énoncé, une problématique courante n’est pas prise en compte:

Lors du développement en équipe, un fichier source va évoluer à travers plusieurs versions (qui seront bien évidemment stockées dans le Source Control de votre TFS adoré), il faut donc trouver la version correspondante au binaire car debugger un .exe d’il y a 6 mois avec les dernières: ca ne marche pas top!

Malheureusement, lorsque le .pdb est généré par le compilateur, il n’y a aucune trace de version. Cela peut se comprendre car le compilateur n’est en aucun cas lié au système de gestion de configuration, pour lui il compile des fichiers sans aucune notion de versionning. A moins de mettre toutes vos sources et livrables d’une Build donnée dans un répertoire spécifique (ce qui devient vite l’usine à gaz), il faut pouvoir lier le .pdb au source control.

La solution (toujours théorique)

Ca tombe bien, car le .pdb peut gérer l’extraction de sources à partir d’un source control (pour autant que celui-ci peut être invoqué en ligne de commande).

Il est possible de modifier un .pdb généré par le compilateur pour y modifier le référencement et l’accès des fichiers sources. Je vais vous épargner la procédure qui permet de faire cette opération manuellement car TFS le fait pour vous, mais pour les curieux, si vous ouvrez avec notepad un fichier .pdb généré avec la procédure que je vais vous exposer, vous trouverez parmi le vacarme binaire un fragment texte similaire à celui-ci:

SRCSRV: ini ————————————————
VERSION=3
INDEXVERSION=2
VERCTRL=Team Foundation Server
DATETIME=Mon May 16 21:22:30 2011
INDEXER=TFSTB
SRCSRV: variables ——————————————
TFS_EXTRACT_CMD=tf.exe view /version:%var4% /noprompt "$%var3%" /server:%fnvar%(%var2%) /console >%srcsrvtrg%
TFS_EXTRACT_TARGET=%targ%\%var2%%fnbksl%(%var3%)\%fnfile%(%var5%)
SRCSRVVERCTRL=tfs
SRCSRVERRDESC=access
SRCSRVERRVAR=var2
VSTFSSERVER=
http://mytfs:8080/tfs/TPC
SRCSRVTRG=%TFS_extract_target%
SRCSRVCMD=%TFS_extract_cmd%
SRCSRV: source files —————————————
C:\Builds\1\Test\Sources\Main\Applications\WpfApp1\App.xaml*VSTFSSERVER*/Test/Main/Applications/WpfApp1/App.xaml*323*App;C323.xaml
C:\Builds\1\Test\Sources\Main\Applications\WpfApp1\MainWindow.xaml.cs*VSTFSSERVER*/Test/Main/Applications/WpfApp1/MainWindow.xaml.cs*323*MainWindow.xaml;C323.cs
SRCSRV: end ————————————————

On y voit clairement l’URL du serveur TFS, la commande pour extraire un fichier du source control en fonction de sa version (son ChangeSet), puis une liste de correspondance pour obtenir le fichier du source control à partir de son chemin absolue (tel qu’il sera exprimé dans le reste du .pdb).

Le moment tant attendu: action!

Bon, maintenant on passe à la pratique, celle-ci se découpe en deux phases, ca sera bref, promis!

Configuration de la définition de la Build

A partir d’une définition de Build existante vous allez veiller à ce que les paramètres suivants soit configurés.

Dans l’onglet Process, dépliez la section “Source And Symbol Server Settings”:

image image

L’option “Index Souces” activera l’exécution de l’activité IndexSources (Ô surprise!) du Workflow de votre Build, celle-ci aura pour but de modifier les .pdb générés pour y inscrire les informations relatives au versionning.

Le chemin de “Path to Publish Symbols” sera utilisé par l’activité PublishSymbols (et re!) pour copier votre .pdb et mettre un répertoire réseau utilisé comme serveur de symboles dans votre entreprise (ce qui nécessite un peu plus de travail qu’une copie de .pdb, en faite). La plus part du temps ce sera un répertoire qui se trouve au même endroit que le “Build Drop Folder” et qui aura les mêmes permissions/droits d’accès.

Et voilà pour la partie serveur.

Configuration de Visual Studio

La partie du .pdb dédiée à l’extraction de fichier n’est utilisé que si celui-ci est consommé dans le cadre d’un serveur de symboles. Il faut donc configurer votre Visual Studio pour utiliser celui mis à jour par votre Team Build.

Menu Tool, puis Options…, puis Debugging/General

image

En cochant la première case, on autorisera ainsi l’utilisation des serveur de symboles par le débuggeur. La deuxième est optionnelle, mais je recommande dans un premier temps, histoire de s’assurer que tout va bien!

Toujours dans la section Debugging, mais dans la sous-section Symbols

image

On rajoute une nouvelle entré en cliquant sur l’icône de création de dossier (en haut à droite). Puis on indique son UNC.

Attention! Toujours dans ce dialogue, l’option par défaut pour “Automatically load symbols for:” est à “Only specified modules” ce qui aura pour avantage de ne pas aller chercher sur le réseau (ou internet si comme moi vous référencez le serveur de Microsoft) systématiquement lorsqu’un binaire est chargé par le débuggeur, mais comme inconvénient de devoir demander le chargement des symboles manuellement…à chaque session de debugging!

Bref, je vous conseil de faire comme moi: chargement systématique, de toute façon tout est mis en cache en local, donc vous souffrirez la première fois, mais après ca ira!

Conclusion

A partir de maintenant vous pourrez debugger n’importe quel binaire produit par votre chaine d’intégration continue, sans effort ni peine, le cout est faible, profitez s’en, une fois que c’est configuré vous ne pourrez plus vous en passer!

Vive les progrès de la technologie moderne! Rire