Watchpoint — o que é, tipos e configuração de pontos de observação no Xcode

Autor: IT Sectr Publicado: 2026-05-07 Tempo de leitura: 8 min

Watchpoint (ponto de observação) — um mecanismo de depuração que pausa a execução do programa quando o valor de uma variável ou região de memória especificada muda. Ao contrário de um breakpoint, que está vinculado a uma linha de código, um watchpoint rastreia alterações de dados independentemente de onde no programa a modificação ocorre. De acordo com a Apple Developer Documentation, os watchpoints são indispensáveis para depurar condições de corrida, alterações inesperadas de propriedades e rastrear ciclos de vida de objetos.

Pontos principais

  • Watchpoint — um ponto que monitora uma variável para alterações, acionado em qualquer escrita na região de memória especificada.
  • Xcode suporta watchpoints via GUI e console LLDB, incluindo watchpoints condicionais.
  • Variáveis de propriedade de objetos requerem um watchpoint com o endereço de memória em vez do nome da variável.
  • O desempenho com watchpoints degrada significativamente devido ao monitoramento de hardware de cada operação de escrita.
  • Watchpoints não são preservados entre sessões de depuração — devem ser configurados novamente após cada inicialização.

O que é um watchpoint e como funciona

Watchpoint — é um mecanismo do depurador que pausa a execução do programa quando o valor em um endereço de memória especificado muda. Se um breakpoint reage ao atingir uma linha específica de código, um watchpoint reage à escrita em uma célula de memória específica — independentemente de qual parte do código realizou a escrita. Isso o torna indispensável para encontrar modificações inesperadas de variáveis, especialmente em aplicações multithread.

O princípio de funcionamento é baseado no suporte de hardware do processador. Chips ARM modernos (Apple Silicon, Qualcomm Snapdragon) fornecem de 4 a 8 registradores de watchpoint de hardware. Quando o processador executa uma instrução de escrita em um endereço que corresponde a um watchpoint, ocorre uma interrupção de hardware que o depurador captura. Quando os registradores de hardware se esgotam, o LLDB muda para o modo software — ele verifica passo a passo cada instrução de escrita, retardando a execução dezenas de vezes.

De acordo com o ARM Architecture Reference Manual, os watchpoints de hardware operam no nível do módulo Data Watchpoint and Trace (DWT) e não requerem modificação do código executável. O tempo de resposta é em nanossegundos, permitindo rastrear até alterações de alta frequência em loops de processamento de dados, como buffers de áudio ou quadros de vídeo.

Quando um watchpoint é mais eficaz que um breakpoint

Watchpoint é indispensável quando você sabe qual variável está mudando mas não sabe de onde. Cenários típicos: uma propriedade frame de UIView muda sem motivo aparente; um contador em uma thread de fundo redefine-se imprevisivelmente; uma flag isLoading alterna antes de uma requisição de rede ser concluída. Em cada um desses casos, configurar breakpoints em todos os lugares onde uma escrita poderia ocorrer é impraticável. Um watchpoint resolve o problema com um único comando.

Tipos de watchpoints e formas de configuração

Xcode e LLDB suportam três tipos de watchpoints: watchpoint set variable — para monitorar uma variável local; watchpoint set expression — para monitorar uma expressão que retorna um endereço; watchpoint set — para monitorar um endereço de memória bruto. Cada tipo tem sua área de aplicação.

Tipo de watchpointComando LLDBUso
Variávelwatchpoint set variable -w write self.countVariáveis locais e globais, propriedades de structs
Expressãowatchpoint set expression -w write -- &self->mutex.lockCampos de structs por ponteiro, elementos de array por índice
Endereçowatchpoint set -w write 0x600000c4b80Endereço de memória específico da saída anterior do LLDB

Configuração via GUI do Xcode

No Xcode, você pode configurar um watchpoint através da Área de Depuração: pare em um breakpoint, encontre a variável desejada no painel Variables View, clique com o botão direito e selecione Watch Variable. O Xcode executará automaticamente o comando watchpoint set variable com o nome e contexto corretos da variável. Depois disso, o depurador pausará a cada alteração de valor — conveniente para depuração rápida sem alternar para o console. No entanto, este método só funciona enquanto a variável estiver no escopo do frame atual.

swift
func processItems(_ items: [String]) {
    var index = 0
    // Definir watchpoint no índice via GUI:
    // pare aqui, clique direito → Watch Variable
    for item in items {
        index += 1
        print("Item \(index): \(item)")
    }
}

Gerenciamento de watchpoints via LLDB

LLDB fornece um conjunto completo de comandos para gerenciar watchpoints a partir do console. Isso oferece mais controle que a GUI: você pode definir o tamanho da região de observação, especificar condições de disparo, criar watchpoints em endereços obtidos de expressões computadas e executar automaticamente ações ao disparar. A interface de comandos é especialmente útil ao depurar cenários complexos que exigem mudança rápida dos parâmetros de observação.

Comandos básicos de watchpoint

O comando watchpoint set variable recebe um nome de variável considerando o escopo: para propriedades self do Objective-C use self->_property, para Swift use self.property. O parâmetro -w write define o rastreamento de escrita, -w read — rastreamento de leitura (um modo disponível apenas em algumas arquiteturas), -s size — o tamanho da região em bytes. Após configurar um watchpoint, você pode ver a lista com o comando 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 condicionais

Assim como os breakpoints, os watchpoints suportam disparo condicional. O parâmetro -c define uma condição em Swift ou Objective-C. Por exemplo, um watchpoint com a condição newValue > 1000 só parará quando o valor escrito exceder mil. Isso é crítico ao depurar loops ou sensores que geram milhares de alterações por segundo — caso contrário, o depurador pararia em cada alteração, tornando o trabalho impossível.

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
// Registrar valor automaticamente e continuar a execução

Watchpoints para propriedades de objetos e coleções

Uma característica específica dos watchpoints para propriedades de objetos Objective-C e Swift — um watchpoint é definido não no nome da propriedade mas no endereço do campo ivar (variável de instância) na memória do objeto. Isso significa que a cada nova alocação de objeto (por exemplo, ao recriar um ViewController), o watchpoint torna-se inválido porque o endereço de memória mudou. Para monitoramento persistente de uma propriedade entre reinicializações, é necessário redefinir o watchpoint no momento da inicialização do objeto.

Watchpoint em elementos de coleções

Monitorar elementos de arrays e dicionários requer calcular o endereço de um elemento específico. Por exemplo, para monitorar o terceiro elemento de um array use watchpoint set expression -- &array[2]. Se o array realocar seu buffer interno (ao adicionar elementos além da capacidade), o watchpoint torna-se inválido — o LLDB reportará um erro Watchpoint 1 has an invalid address. Nesses casos, você precisa redefinir o watchpoint após alterar o tamanho da coleção.

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

Rastreamento de retain count via watchpoint

Em Objective-C, você pode rastrear o retain count de um objeto definindo um watchpoint no campo retainCount da estrutura objc_object. O LLDB faz isso através de watchpoint set expression -w write -- (int*)[object retainCount]. No entanto, para objetos Swift com ARC (Automatic Reference Counting), o retain count não é acessível diretamente — em vez disso, use Instruments ou Memory Graph Debugger para análise de vazamentos. De acordo com a Apple, watchpoints em retain count só funcionam em compilações Debug com otimização ARC desabilitada.

Limitações e desempenho dos watchpoints

Watchpoints têm várias limitações importantes a considerar. A principal — o número de watchpoints de hardware é limitado a 4–8 registradores na arquitetura ARM e até 4 no x86. Quando todos os registradores de hardware estão ocupados, o LLDB muda para o modo de watchpoint software: modifica cada instrução de escrita no intervalo rastreado para gerar uma exceção. Isso retarda a execução em 10–50 vezes, então na prática é recomendado usar não mais que 2–3 watchpoints ativos simultaneamente.

A segunda limitação — invalidação de watchpoints ao realocar memória. Quando a coleta de lixo ou ARC é acionada, e um objeto se move na memória (em linguagens com compactação de heap), o endereço do watchpoint torna-se incorreto. Em Swift e Objective-C, o ARC não move objetos, mas a realocação de arrays e strings causa o mesmo efeito. O LLDB avisa sobre isso com a mensagem Watchpoint N address (0x...) doesn’t contain a valid allocation.

A terceira limitação — visibilidade de variáveis. Um watchpoint em uma variável local só funciona enquanto essa variável estiver dentro do escopo do frame de pilha atual. Assim que a função termina, o watchpoint é removido automaticamente. Para monitorar variáveis globais ou campos de objetos de longa duração, um watchpoint persiste até ser explicitamente excluído via watchpoint delete ou até o processo terminar.

lldb
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete               # Excluir todos os watchpoints
2 watchpoints deleted.
(lldb) watchpoint disable 1             # Desabilitar temporariamente
(lldb) watchpoint enable 1              # Habilitar novamente

De acordo com a ARM, watchpoints no Apple Silicon (M1–M4) suportam um tamanho de região monitorada de 1 a 8 bytes. Para monitorar estruturas maiores que 8 bytes, você precisa definir vários watchpoints em cada campo. Isso é importante ao depurar estruturas de dados complexas como CGRect (16 bytes) ou UIEdgeInsets (16 bytes).

Perguntas frequentes

Qual é a diferença entre um watchpoint e um breakpoint?

Breakpoint está vinculado a uma linha de código — para quando essa linha é atingida. Watchpoint está vinculado a um endereço de memória — para quando uma escrita ocorre nesse endereço de qualquer lugar do programa. Um watchpoint procura “quem está mudando o valor”, um breakpoint procura “o que acontece nesta linha”.

Quantos watchpoints podem ser configurados simultaneamente?

4–8 watchpoints de hardware no ARM (incluindo Apple Silicon). Exceder isso muda o watchpoint para modo software, retardando a execução em 10–50 vezes. Recomenda-se não usar mais de 2–3 watchpoints ativos por vez.

Por que um watchpoint para de funcionar após reiniciar o aplicativo?

Watchpoints não são preservados entre sessões de depuração. Em cada nova inicialização, os endereços de memória mudam e o watchpoint deve ser configurado novamente. A exceção são watchpoints em variáveis globais com endereço fixo.

Posso configurar um watchpoint em uma propriedade Swift?

Sim, mas o watchpoint é definido no ivar (armazenamento subjacente) da propriedade, não na propriedade em si. Em Swift, use watchpoint set variable self.property — o LLDB encontrará automaticamente o ivar correspondente pelo nome da propriedade.

Como um watchpoint afeta o desempenho do aplicativo?

Watchpoints de hardware não afetam o desempenho — a interrupção ocorre no nível do processador. Watchpoints de software (quando os registradores de hardware se esgotam) retardam a execução em 10–50 vezes, pois o LLDB verifica cada instrução de escrita.

Resumo

  • Watchpoint — um ponto que monitora alterações na memória, acionado em qualquer escrita no endereço especificado de qualquer thread.
  • Watchpoints de hardware usam registradores DWT do processador e não retardam a execução, mas são limitados a 4–8 registradores.
  • LLDB suporta três tipos de watchpoints: em uma variável, em uma expressão e em um endereço de memória bruto.
  • Watchpoints condicionais só disparam quando uma expressão especificada é avaliada como verdadeira — essencial para depurar alterações de alta frequência.
  • Watchpoints em propriedades de objetos e elementos de coleções tornam-se inválidos ao realocar memória.
  • Watchpoints não são preservados entre sessões e são removidos quando uma variável sai do escopo.
  • Watchpoint é a melhor escolha quando a variável é conhecida mas o local de sua modificação não, especialmente em código multithread.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também