Skip to content

Le format de fichier tracev3 expliqué

Au cœur des fichiers tracev3 de macOS : en-tête, catalogue, chunksets LZ4, chunks firehose, oversize, statedump, chaînes uuidtext et dsc, timesync.

Publié le 5 min de lecture

En bref. Un fichier .tracev3 est un flux de chunks. Un chunk d'en-tête décrit la machine et le démarrage, des chunks de catalogue listent les processus et les subsystems, et chaque catalogue est suivi de chunksets — des blocs compressés en LZ4 contenant les entrées firehose (les messages de journal), les chaînes oversize, et les enregistrements statedump et simpledump. Le texte provient des fichiers uuidtext et dsc, l'heure des fichiers timesync. C'est cette structure que décode Unified Log Parser, à l'aide du parseur open source de Mandiant compilé en WebAssembly.

La structure décrite ci-dessous s'appuie sur les travaux publics de rétro-ingénierie de Mandiant (macos-UnifiedLogs) et de Joachim Metz (libyal dtformats). Apple ne documente pas ce format, et les champs signalés comme inconnus dans ces sources le sont aussi ici.

Chunks et préambules

Chaque chunk commence par un préambule de 16 octets : un tag sur 32 bits, un sous-tag sur 32 bits et une taille de données sur 64 bits. Les chunks sont alignés sur 8 octets. Les tags qui comptent :

TagChunk
0x1000En-tête
0x600bCatalogue
0x600dChunkset (compressé)
0x6001Firehose (dans un chunkset)
0x6002Oversize (dans un chunkset)
0x6003Statedump (dans un chunkset)
0x6004Simpledump (dans un chunkset)

Un fichier commence donc toujours par les octets 00 10 00 00 : c'est ainsi que le parseur le reconnaît, quel que soit son nom.

En-tête

L'en-tête enregistre la base de temps Mach (numérateur et dénominateur), le temps continu au moment de la création du fichier, le décalage de fuseau horaire et l'indicateur d'heure d'été, ainsi que des sous-chunks contenant la version de build (par exemple 25G83), le modèle matériel (Mac14,14), l'UUID de démarrage, le PID de logd et le chemin du fichier de fuseau horaire. L'UUID de démarrage rattache chaque entrée à une session de démarrage et aux bons enregistrements timesync. L'onglet Sources du parseur affiche ces valeurs.

Catalogue

Un catalogue décrit les entrées des chunksets qui le suivent :

  • un tableau d'UUID — ceux des binaires qui ont journalisé et celui du cache partagé ;
  • une table des chaînes de subsystems et de catégories ;
  • des entrées de processus : PID, identifiant utilisateur effectif, index de l'UUID de l'exécutable principal et de celui du cache partagé, UUID supplémentaires (bibliothèques chargées) avec leurs adresses de chargement, et subsystems utilisés par le processus ;
  • des descripteurs de sous-chunks : intervalle de temps, taille décompressée et algorithme de compression de chaque chunkset.

Les entrées firehose désignent leur processus par une paire d'identifiants résolue dans cette table, et leur subsystem par un petit index.

Chunksets

Un chunkset est un bloc compressé. La plupart utilisent LZ4 avec l'en-tête de bloc bv41 propre à Apple (bv41- signale un bloc non compressé) ; les versions récentes peuvent aussi utiliser LZBITMAP, que le parseur prend en charge. Une fois décompressé, un chunkset est à nouveau une suite de chunks.

Firehose

Un chunk firehose comporte un préambule avec un temps continu de base, puis des entrées. Chaque entrée possède un type d'activité (log, activity, trace, signpost, loss), un type de journal (Default, Info, Debug, Error, Fault, ou un type de signpost), des indicateurs, un identifiant de thread, un delta temporel et une zone de données. Les indicateurs précisent où se trouve la chaîne de format : dans le fichier uuidtext propre au processus (exécutable principal), dans le cache partagé (dsc), à un décalage absolu, ou relativement à un autre UUID. La zone de données contient les arguments — nombres, chaînes, ou références vers des données privées et des chaînes oversize.

Oversize

Les arguments trop volumineux pour l'entrée sont stockés dans des chunks oversize, identifiés par une référence de données. Ils peuvent se trouver dans un fichier ultérieur à celui de l'entrée qui les référence : c'est pourquoi un parseur doit conserver les données oversize d'un fichier à l'autre et retenter la résolution des entrées en suspens à la fin.

Statedump et simpledump

Les statedumps sont des instantanés qu'un processus écrit à la demande — une plist, un protobuf ou un objet personnalisé doté d'un titre (la « TCC Authorization Cache » en est un). Les simpledumps sont des messages courts journalisés sans chaîne de format par launchd et quelques autres processus.

uuidtext et dsc : le texte manquant

Un fichier uuidtext (/private/var/db/uuidtext/XX/…, où XX est le premier octet de l'UUID et le nom du fichier correspond aux 30 chiffres hexadécimaux restants) commence par la signature 0x66778899, liste des plages de l'espace d'adressage du binaire, contient les chaînes de format correspondantes et se termine par le chemin du binaire. Un fichier dsc (uuidtext/dsc/<32 hex>, signature hcsd) fait de même pour l'ensemble du cache partagé dyld et nomme chacun des frameworks qu'il contient.

Pour restituer un message, le parseur identifie le bon fichier à partir de l'UUID du catalogue et des indicateurs de l'entrée, lit la chaîne de format au décalage enregistré et applique les arguments à la manière de printf : %d, %s, %@, %{public}s, %{private}@ et des décodeurs de type comme %{errno}d, %{uuid_t}.16P ou %{bool}d. Les arguments privés qui n'ont pas été capturés apparaissent sous la forme <private>.

timesync

Les fichiers timesync contiennent, pour chaque UUID de démarrage, un en-tête (signature 0xbbb0, base de temps, heure de démarrage) et des enregistrements associant un temps continu à une heure réelle. L'heure réelle d'une entrée correspond à l'heure de l'enregistrement précédent le plus proche, augmentée du temps continu écoulé multiplié par la base de temps — 125/3 sur Apple silicon, 1/1 sur Intel.

Ce que cela implique en pratique

  • Collectez uuidtext, dsc et timesync avec les fichiers tracev3 (guide de collecte).
  • Attendez-vous malgré tout à quelques entrées « non résolues » : une chaîne peut manquer dans les fichiers qu'Apple a conservés.
  • Comparez les entrées importantes avec log show. Validé sur une archive réelle, le parseur a restitué à l'identique environ 99 % des messages de type log, activity et state ; seule la présentation des signposts diffère.

Consultez le glossaire pour chaque terme, ou ouvrez vos propres fichiers dans le parseur.

Articles liés

Pas à pas : ouvrir une .logarchive, un dossier diagnostics ou un export log show dans Unified Log Parser, trier les constats, cibler et exporter.
Collecter les journaux unifiés macOS avec log collect, une copie brute de diagnostics et uuidtext, UAC, Velociraptor ou mac_apt, sans lacunes.
Ce qu'enregistrent les journaux unifiés macOS, où se trouvent tracev3, uuidtext et timesync, ce qu'ils prouvent ou non, et une méthode d'analyse.