Watchpoint — qu'est-ce que c'est, types et configuration des points d'observation dans Xcode

Auteur : IT Sectr Publié le : 2026-05-07 Temps de lecture : 8 min

Watchpoint (point d'observation) — un mécanisme de débogage qui suspend l'exécution du programme lorsque la valeur d'une variable ou d'une région mémoire spécifiée change. Contrairement à un breakpoint, qui est lié à une ligne de code, un watchpoint suit les modifications de données indépendamment de l'endroit du programme où la modification se produit. Selon la Apple Developer Documentation, les watchpoints sont indispensables pour déboguer les courses de données, les changements inattendus de propriétés et le suivi des cycles de vie des objets.

Points clés

  • Watchpoint — un point qui surveille une variable pour détecter les changements, déclenché sur toute écriture dans la région mémoire spécifiée.
  • Xcode prend en charge les watchpoints via l'interface graphique et la console LLDB, y compris les watchpoints conditionnels.
  • Les variables-propriétés des objets nécessitent un watchpoint avec l'adresse mémoire plutôt que le nom de la variable.
  • Les performances avec les watchpoints se dégradent considérablement en raison de la surveillance matérielle de chaque opération d'écriture.
  • Les watchpoints ne sont pas conservés entre les sessions de débogage — ils doivent être redéfinis après chaque lancement.

Qu'est-ce qu'un watchpoint et comment il fonctionne

Watchpoint — est un mécanisme du débogueur qui suspend l'exécution du programme lorsque la valeur à une adresse mémoire spécifiée change. Si un breakpoint réagit à l'atteinte d'une ligne de code spécifique, un watchpoint réagit à l'écriture dans une cellule mémoire spécifique — indépendamment de la partie du code qui a effectué l'écriture. Cela le rend indispensable pour trouver des modifications inattendues de variables, en particulier dans les applications multithread.

Le principe de fonctionnement est basé sur le support matériel du processeur. Les puces ARM modernes (Apple Silicon, Qualcomm Snapdragon) fournissent de 4 à 8 registres matériels de watchpoint. Lorsque le processeur exécute une instruction d'écriture à une adresse correspondant à un watchpoint, une interruption matérielle se produit, que le débogueur intercepte. Lorsque les registres matériels sont épuisés, LLDB passe en mode logiciel — il vérifie pas à pas chaque instruction d'écriture, ralentissant l'exécution de dizaines de fois.

Selon le ARM Architecture Reference Manual, les watchpoints matériels opèrent au niveau du module Data Watchpoint and Trace (DWT) et ne nécessitent pas de modification du code exécutable. Le temps de réponse est de l'ordre de la nanoseconde, permettant de suivre même les changements à haute fréquence dans les boucles de traitement de données comme les tampons audio ou les trames vidéo.

Quand un watchpoint est plus efficace qu'un breakpoint

Watchpoint est indispensable lorsque vous savez quelle variable change mais pas d'où. Scénarios typiques : une propriété frame d'UIView change sans raison apparente ; un compteur dans un thread d'arrière-plan se réinitialise de façon imprévisible ; un indicateur isLoading bascule avant qu'une requête réseau ne soit terminée. Dans chacun de ces cas, placer des breakpoints à tous les endroits où une écriture pourrait se produire est peu pratique. Un watchpoint résout le problème avec une seule commande.

Types de watchpoints et méthodes de configuration

Xcode et LLDB prennent en charge trois types de watchpoints : watchpoint set variable — pour surveiller une variable locale ; watchpoint set expression — pour surveiller une expression qui retourne une adresse ; watchpoint set — pour surveiller une adresse mémoire brute. Chaque type a son domaine d'application.

Type de watchpointCommande LLDBUtilisation
Variablewatchpoint set variable -w write self.countVariables locales et globales, propriétés de structures
Expressionwatchpoint set expression -w write -- &self->mutex.lockChamps de structures par pointeur, éléments de tableau par index
Adressewatchpoint set -w write 0x600000c4b80Adresse mémoire spécifique d'une sortie précédente de LLDB

Configuration via l'interface graphique de Xcode

Dans Xcode, vous pouvez configurer un watchpoint via la zone de débogage : arrêtez-vous sur un breakpoint, trouvez la variable souhaitée dans le panneau Variables View, faites un clic droit et sélectionnez Watch Variable. Xcode exécutera automatiquement la commande watchpoint set variable avec le nom de variable et le contexte corrects. Après cela, le débogueur s'arrêtera à chaque changement de valeur — pratique pour un débogage rapide sans basculer vers la console. Cependant, cette méthode ne fonctionne que tant que la variable est dans la portée du frame actuel.

swift
func processItems(_ items: [String]) {
    var index = 0
    // Définir un watchpoint sur l'index via l'interface graphique :
    // arrêtez-vous ici, clic droit → Watch Variable
    for item in items {
        index += 1
        print("Élément \(index) : \(item)")
    }
}

Gestion des watchpoints via LLDB

LLDB fournit un ensemble complet de commandes pour gérer les watchpoints depuis la console. Cela offre plus de contrôle que l'interface graphique : vous pouvez définir la taille de la région d'observation, spécifier des conditions de déclenchement, créer des watchpoints sur des adresses obtenues à partir d'expressions calculées et exécuter automatiquement des actions lors du déclenchement. L'interface en ligne de commande est particulièrement utile pour déboguer des scénarios complexes nécessitant de changer rapidement les paramètres d'observation.

Commandes de base des watchpoints

La commande watchpoint set variable prend un nom de variable en tenant compte de la portée : pour les propriétés self d'Objective-C, utilisez self->_property, pour Swift, utilisez self.property. Le paramètre -w write définit le suivi d'écriture, -w read — le suivi de lecture (un mode disponible uniquement sur certaines architectures), -s size — la taille de la région en octets. Après avoir défini un watchpoint, vous pouvez afficher la liste avec la commande watchpoint list.

lldb
(lldb) watchpoint set variable -w write -s 8 self.balance
Watchpoint 1: addr = 0x600000c4b80 size = 8 state = enabled  type = w
    watchpoint spec: 'self.balance'
(lldb) watchpoint set expression -w write -- self->items._storage
Watchpoint 2: addr = 0x600003a4c00 size = 8
(lldb) watchpoint list
1: location = 0x600000c4b80, type = write, variable = '_balance'
2: location = 0x600003a4c00, type = write, expression = 'self->items._storage'

Watchpoints conditionnels

Comme les breakpoints, les watchpoints prennent en charge le déclenchement conditionnel. Le paramètre -c définit une condition en Swift ou Objective-C. Par exemple, un watchpoint avec la condition newValue > 1000 ne s'arrêtera que lorsque la valeur écrite dépasse mille. Ceci est crucial lors du débogage de boucles ou de capteurs générant des milliers de changements par seconde — sinon le débogueur s'arrêterait à chaque changement, rendant le travail impossible.

lldb
(lldb) watchpoint set variable -w write self.temperature -c "(int)$newValue > 100"
Watchpoint 3: addr = 0x600000e4a20, condition = '(int)$newValue > 100'
(lldb) watchpoint modify 3 -C "po self.temperature" -G true
// Journaliser automatiquement la valeur et continuer l'exécution

Watchpoints pour les propriétés d'objets et les collections

Une caractéristique spécifique des watchpoints pour les propriétés d'objets Objective-C et Swift — un watchpoint est défini non pas sur le nom de la propriété mais sur l'adresse du champ ivar (variable d'instance) dans la mémoire de l'objet. Cela signifie qu'à chaque nouvelle allocation d'objet (par exemple, lors de la recréation d'un ViewController), le watchpoint devient invalide car l'adresse mémoire a changé. Pour une surveillance persistante d'une propriété entre les redémarrages, vous devez redéfinir le watchpoint au moment de l'initialisation de l'objet.

Watchpoint sur les éléments de collections

La surveillance d'éléments de tableaux et de dictionnaires nécessite de calculer l'adresse d'un élément spécifique. Par exemple, pour surveiller le troisième élément d'un tableau, utilisez watchpoint set expression -- &array[2]. Si le tableau réalloue son tampon interne (en ajoutant des éléments au-delà de la capacité), le watchpoint devient invalide — LLDB signalera une erreur Watchpoint 1 has an invalid address. Dans ces cas, vous devez redéfinir le watchpoint après avoir modifié la taille de la collection.

lldb
(lldb) expr var $arr = [10, 20, 30, 40, 50]
(lldb) watchpoint set expression -w write -- &$arr[2]
Watchpoint 4: addr = 0x1000a4b20, size = 8
(lldb) expr $arr[2] = 99
Watchpoint 4 hit: old value: 30, new value: 99

Suivi du retain count via watchpoint

En Objective-C, vous pouvez suivre le retain count d'un objet en définissant un watchpoint sur le champ retainCount de la structure objc_object. LLDB le fait via watchpoint set expression -w write -- (int*)[object retainCount]. Cependant, pour les objets Swift avec ARC (Automatic Reference Counting), le retain count n'est pas directement accessible — utilisez plutôt Instruments ou le Memory Graph Debugger pour l'analyse des fuites. Selon Apple, les watchpoints sur le retain count ne fonctionnent que dans les builds Debug avec l'optimisation ARC désactivée.

Limitations et performances des watchpoints

Les watchpoints ont plusieurs limitations importantes à considérer. La principale — le nombre de watchpoints matériels est limité à 4–8 registres sur l'architecture ARM et jusqu'à 4 sur x86. Lorsque tous les registres matériels sont occupés, LLDB passe en mode watchpoint logiciel : il modifie chaque instruction d'écriture dans la plage surveillée pour générer une exception. Cela ralentit l'exécution de 10 à 50 fois, donc en pratique il est recommandé d'utiliser pas plus de 2–3 watchpoints actifs simultanément.

La deuxième limitation — l'invalidation des watchpoints lors de la réallocation mémoire. Lorsque le ramasse-miettes ou ARC se déclenche, et qu'un objet se déplace en mémoire (dans les langues avec compactage du tas), l'adresse du watchpoint devient incorrecte. En Swift et Objective-C, ARC ne déplace pas les objets, mais la réallocation de tableaux et de chaînes provoque le même effet. LLDB en avertit avec le message Watchpoint N address (0x...) doesn’t contain a valid allocation.

La troisième limitation — la visibilité des variables. Un watchpoint sur une variable locale ne fonctionne que tant que cette variable est dans la portée du frame de pile actuel. Dès que la fonction se termine, le watchpoint est automatiquement supprimé. Pour surveiller des variables globales ou des champs d'objets à longue durée de vie, un watchpoint persiste jusqu'à sa suppression explicite via watchpoint delete ou jusqu'à la fin du processus.

lldb
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete               # Supprimer tous les watchpoints
2 watchpoints deleted.
(lldb) watchpoint disable 1             # Désactiver temporairement
(lldb) watchpoint enable 1              # Réactiver

Selon ARM, les watchpoints sur Apple Silicon (M1–M4) prennent en charge une taille de région surveillée de 1 à 8 octets. Pour surveiller des structures de plus de 8 octets, vous devez définir plusieurs watchpoints sur chaque champ. Ceci est important lors du débogage de structures de données complexes comme CGRect (16 octets) ou UIEdgeInsets (16 octets).

Questions fréquentes

Quelle est la différence entre un watchpoint et un breakpoint ?

Breakpoint est lié à une ligne de code — il s'arrête lorsque cette ligne est atteinte. Watchpoint est lié à une adresse mémoire — il s'arrête lorsqu'une écriture se produit à cette adresse depuis n'importe où dans le programme. Un watchpoint cherche « qui change la valeur », un breakpoint cherche « ce qui se passe sur cette ligne ».

Combien de watchpoints peut-on définir simultanément ?

4–8 watchpoints matériels sur ARM (y compris Apple Silicon). Le dépassement fait passer le watchpoint en mode logiciel, ralentissant l'exécution de 10 à 50 fois. Il est recommandé de ne pas utiliser plus de 2–3 watchpoints actifs à la fois.

Pourquoi un watchpoint cesse-t-il de fonctionner après un redémarrage de l'application ?

Les watchpoints ne sont pas conservés entre les sessions de débogage. À chaque nouveau lancement, les adresses mémoire changent et le watchpoint doit être redéfini. L'exception concerne les watchpoints sur les variables globales avec une adresse fixe.

Peut-on définir un watchpoint sur une propriété Swift ?

Oui, mais le watchpoint est défini sur l'ivar (stockage de soutien) de la propriété, pas sur la propriété elle-même. En Swift, utilisez watchpoint set variable self.property — LLDB trouvera automatiquement l'ivar correspondant par le nom de la propriété.

Comment un watchpoint affecte-t-il les performances de l'application ?

Les watchpoints matériels n'affectent pas les performances — l'interruption se produit au niveau du processeur. Les watchpoints logiciels (lorsque les registres matériels sont épuisés) ralentissent l'exécution de 10 à 50 fois, car LLDB vérifie chaque instruction d'écriture.

Résumé

  • Watchpoint — un point qui surveille les changements mémoire, déclenché sur toute écriture à l'adresse spécifiée depuis n'importe quel thread.
  • Les watchpoints matériels utilisent les registres DWT du processeur et ne ralentissent pas l'exécution, mais sont limités à 4–8 registres.
  • LLDB prend en charge trois types de watchpoints : sur une variable, sur une expression et sur une adresse mémoire brute.
  • Les watchpoints conditionnels ne se déclenchent que lorsqu'une expression spécifiée est évaluée comme vraie — essentiel pour déboguer les changements à haute fréquence.
  • Les watchpoints sur les propriétés d'objets et les éléments de collections deviennent invalides lors de la réallocation mémoire.
  • Les watchpoints ne sont pas conservés entre les sessions et sont supprimés lorsqu'une variable sort de la portée.
  • Watchpoint est le meilleur choix quand la variable est connue mais l'endroit de sa modification ne l'est pas, surtout dans le code multithread.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi