# Dépannage

> Toutes les façons dont un programme invité peut s’arrêter avant une preuve vérifiée, classées par symptôme. Statuts de sortie, erreurs fatales de l’exécuteur, ELF refusés, programmes refusés, preuves en échec et erreurs du vérificateur, avec la cause et la correction.

Un programme invité peut s’arrêter en six points avant d’obtenir une preuve vérifiée. Trouvez le symptôme, puis la ligne.

## L’exécution se termine avec un statut inattendu

L’exécution s’est terminée et est prouvable; c’est le programme invité qui a choisi d’échouer. Les statuts propres au SDK :

| Statut | Cause | Que faire |
| --- | --- | --- |
| 70 | `commit` dépasserait 16 380 octets | Consignez un condensé de la sortie au lieu de la sortie |
| 71 | une allocation se terminerait au-dessus de `__stack_top − 8 MiB` ou au-dessus du `sp` courant | Rien n’est libéré : l’allocation *totale* de l’exécution doit donc tenir entre l’image et `0x7F80_0000`. Réutilisez les tampons d’une boucle à l’autre et dimensionnez-les avec `with_capacity` ([le tas](https://apogee.gweb3networks.com/docs/launch/write#heap)) |
| 72 | une délégation a répondu ce que son shim refuse : une erreur, ou `-ENOSYS` après le premier appel d’une opération en plusieurs appels | Utilisez les fonctions du SDK plutôt que des cadres bruts, et gardez les opérandes inférieurs à leur module |
| 101 | une panique, qui n’affiche rien | Passez les mêmes entrées dans la compilation pour l’hôte de votre bibliothèque, où le message de panique s’affiche ([tester sur l’hôte](https://apogee.gweb3networks.com/docs/launch/write#host-first)) |

Tout autre statut est votre propre `exit(code)`.

## L’exécution s’arrête sur une erreur fatale

L’émulateur renvoie une `EmuError`, et il n’y a ni statut de sortie ni preuve :

| Erreur | Cause habituelle |
| --- | --- |
| `OutOfBounds` | un pointeur nul ou sauvage (`[0, 0x8000)` est un trou), une lecture de données auxiliaires (*advice*) au-delà de ce que l’hôte a fourni, `advice()` dans une exécution sans données auxiliaires, ou un cadre de délégation qui n’est pas entièrement en RAM |
| `Misaligned` | un accès à un demi-mot ou à un mot par un pointeur non aligné, ou un cadre de délégation mal aligné |
| `NotAnInstruction` | un saut vers un pc qui ne contient aucune instruction, y compris le demi-mot entièrement nul `c.unimp` |
| `IllegalInstruction` | un encodage que la machine n’exécute pas |
| `Ebreak` | un `ebreak`, qui n’a pas de preuve |
| `ClockOverflow` | plus de `2^36 − 1` cycles |
| `PublicInputTooLong`, `JournalTooLong` | une entrée, ou le mot de longueur du journal à la sortie, au-dessus de 16 380 octets |
| `DelegationFrame` | un cadre pour lequel son circuit n’a pas de témoin : un opérande de `MOD_MUL` ou d’`EC_ADD` supérieur ou égal à son module, un sélecteur qui ne désigne rien, un tour keccak au-delà de 23, un groupe SHA-256 au-delà de 15, une voie de Poseidon2 supérieure ou égale à `p` |
| `DelegationFamilyAbsent` | un numéro de délégation que l’image n’a jamais déclaré, sur un chemin de traçage |

## L’ELF est refusé

`artifact-dump`, `host::setup` et les outils refusent un ELF que le chargeur ne peut pas prendre, avec une `LoaderError` :

| Refus | Cause habituelle |
| --- | --- |
| `NotAnElf`, `Truncated` | ce n’est pas l’ELF du programme invité : un fichier `.d`, une écriture partielle |
| `NotRiscV`, `UnsupportedElfType`, `RelocatableElf`, `DynamicElf` | une compilation pour l’hôte, un fichier objet, un PIE ou une compilation à édition de liens dynamique |
| `BadSegment`, `NoExecutableSegment`, `EntryNotAnInstruction` | un `link.ld` modifié, ou aucun `_start` lié |
| `RvcIllegal`, `InstructionTooLong`, `TextTruncated` | des données dans `.text`, comme une table dans de l’assembleur écrit à la main. Jamais le demi-mot nul, qui est attendu |

## Le programme ne s’enregistre pas

L’ELF se charge, mais le programme ne peut pas être décodé en une configuration :

| Refus | Cause et correction |
| --- | --- |
| `Not all opcodes supported: pc=…` | un mot hors de RV32IMA n’importe où dans le code exécutable, atteignable ou non, comme un accès à un CSR ou `fence.i` en assembleur. Retirez-le |
| `TableTooShort` | du code au-delà de la portée de la table d’une famille. Augmentez la hauteur de cette famille : `2^22` atteint 7,9375 MiB de code |
| `ProgramTooLarge` | l’image dépasse `bytecode_size_words`, 4 MiB par défaut. Relevez le plafond dans `ProgramParams` |
| `ImageOutsideWindow` | un octet issu du fichier se trouve au-delà de la fenêtre de RAM 0 à votre hauteur de fenêtre. Augmentez la hauteur de fenêtre |
| `HeightNotOnMenu` | une hauteur qui n’est pas `2^8`, `2^12`, `2^16`, `2^18`, `2^20` ou `2^22` |
| `UnknownDelegation` | l’image déclare un numéro de délégation auquel aucune famille ne répond |

La construction d’une clé échoue aussi si une famille qu’utilise le programme est réglée sous son plancher, `2^20` pour une famille d’instructions et `2^16` pour les familles de fenêtres de RAM, puisqu’aucun circuit n’existe à ces hauteurs.

## Le prouveur échoue

Un prouveur honnête qui prouve ce qu’a exécuté l’émulateur n’échoue pas : un échec désigne donc une entrée qu’il n’aurait pas dû accepter, ou un bogue. Deux cas expliquent la plupart des échecs :

- **Un appel sans preuve.** Un appel système autre qu’`EXIT` et les délégations, qu’une bibliothèque a effectué pour obtenir des données de l’hôte, répond `-ENOSYS` et l’exécution continue, mais le remplissage du prouveur refuse cette ligne et nomme le cycle. Trouvez la dépendance qui demande de l’aléa ou l’heure.
- **Mémoire épuisée.** Le processus est tué alors que des shards sont en cours de traitement. Réduisez le troisième argument de `host::prove`, ou abaissez les hauteurs.

Pour tout le reste, recompilez avec le journal de débogage du prouveur et relancez :

```sh
cargo run --release -p bench --features prover/debug-info -- prove ...
APOGEE_DEBUG=detail <the run> 2>&1 | tee run.log
grep -c 'begin h=' run.log; grep -c 'gkr done' run.log     # unequal: a shard died
grep 'begin h=' run.log | tail -1                           # which one
grep -E 'FAIL|NOT CANONICAL|UNBALANCED|OVER the|NAMES NO|DISAGREES|NOT LOOPING|ABORTED' run.log
```

`self_check FAILED` nomme la première porte en échec de la ligne et la valeur de chaque opérande. [Le journal de débogage](https://apogee.gweb3networks.com/docs/reference/tools#s3) énumère chaque marqueur.

## La vérification échoue

`verify_shard` et `verify_block` renvoient une `VerifyError` dont la classe indique ce qui a cédé :

| Classe | Signification |
| --- | --- |
| `Statement` | l’énoncé ne correspond pas à la clé : nombres de shards, règles des fenêtres, longueurs des charges utiles, listes, ou le condensé global avec lequel la preuve a été amorcée |
| `Malformed` | la forme de la preuve n’est pas celle de son circuit : nombre d’engagements, de sorties, de tours ou d’affirmations |
| `Constraint { layer }` | une porte est violée, ou le sumcheck d’une couche échoue |
| `Lookup { channel }` | un tuple recherché ne figure dans aucune ligne de sa table |
| `MemoryArgument` | les multiensembles de lecture et d’écriture ne se rapprochent pas, ou une fenêtre publique ne contient pas les octets de l’énoncé |
| `Opening` | l’ouverture d’un engagement échoue |

Si vous avez construit la preuve avec le prouveur d’Apogee lui-même, à partir d’une exécution que l’émulateur a acceptée, un échec de vérification signifie que le vérificateur et le prouveur sont en désaccord sur le programme : vérifiez que vous chargez la clé sous laquelle la preuve a été produite, aux mêmes hauteurs, sur la même cérémonie.

## Identité discordante

L’identité que vous avez calculée diffère de celle que vous attendiez :

- **La compilation d’une autre machine.** L’ELF incorpore des chemins absolus : une recompilation ailleurs donne donc une autre image. Comparez avec l’ELF qui a été prouvé, et non avec une nouvelle compilation.
- **D’autres hauteurs.** Chaque hauteur est liée dans l’identité. `artifact-dump tables` indique l’identité aux hauteurs par défaut; votre mise en place peut en utiliser d’autres.
- **Une autre cérémonie.** Un fichier de puissances de tau de Hermez correspond à un autre `τ`, si bien que chaque engagement diffère. Comparez le `[τ]_1` du fichier à [celui de la cérémonie](https://apogee.gweb3networks.com/docs/launch/setup#ceremony).
