# Fehlerbehebung

> Jede Art, auf die ein Gastprogramm vor einem verifizierten Beweis stehen bleibt, nach Symptom geordnet. Exit-Status, fatale Fehler des Executors, zurückgewiesene ELFs, zurückgewiesene Programme, fehlgeschlagene Beweise und Fehler des Verifiers, jeweils mit Ursache und Abhilfe.

Ein Gastprogramm (Guest) kann an sechs Stellen vor einem verifizierten Beweis stehen bleiben. Suchen Sie das Symptom, dann die Zeile.

## Der Lauf endet mit einem Status, den Sie nicht erwartet haben

Der Lauf ist beendet und beweisbar; das Gastprogramm hat sich für einen Fehlschlag entschieden. Die eigenen Statuswerte des SDK:

| Status | Ursache | Was zu tun ist |
| --- | --- | --- |
| 70 | `commit` würde 16.380 Byte überschreiten | Schreiben Sie statt der Ausgabe einen Digest der Ausgabe fest |
| 71 | eine Allokation würde oberhalb von `__stack_top − 8 MiB` oder oberhalb des aktuellen `sp` enden | Nichts wird freigegeben; die *gesamte* Allokation des Laufs muss also zwischen das Image und `0x7F80_0000` passen. Verwenden Sie Puffer über Schleifen hinweg wieder und dimensionieren Sie sie mit `with_capacity` ([der Heap](https://apogee.gweb3networks.com/docs/launch/write#heap)) |
| 72 | eine Delegation hat etwas geantwortet, das ihr Shim zurückweist: einen Fehler oder `-ENOSYS` nach dem ersten Aufruf einer Operation aus mehreren Aufrufen | Verwenden Sie die Funktionen des SDK statt roher Frames und halten Sie Operanden unterhalb ihres Moduls |
| 101 | ein Panic, der nichts ausgibt | Lassen Sie dieselben Eingaben durch den Host-Build Ihrer Bibliothek laufen, wo die Panic-Meldung ausgegeben wird ([auf dem Host testen](https://apogee.gweb3networks.com/docs/launch/write#host-first)) |

Jeder andere Status ist Ihr eigenes `exit(code)`.

## Der Lauf bricht mit einem fatalen Fehler ab

Der Emulator gibt einen `EmuError` zurück, und es gibt weder Exit-Status noch Beweis:

| Fehler | Übliche Ursache |
| --- | --- |
| `OutOfBounds` | ein Null- oder wilder Zeiger (`[0, 0x8000)` ist ein Loch), ein Lesezugriff auf Hilfsdaten (Advice) jenseits dessen, was der Host geliefert hat, `advice()` in einem Lauf ohne Hilfsdaten oder ein Delegations-Frame, der nicht vollständig im RAM liegt |
| `Misaligned` | ein Halbwort- oder Wortzugriff über einen nicht ausgerichteten Zeiger oder ein nicht ausgerichteter Delegations-Frame |
| `NotAnInstruction` | ein Sprung zu einem pc, der keinen Befehl enthält, einschließlich des aus Nullen bestehenden Halbworts `c.unimp` |
| `IllegalInstruction` | eine Kodierung, die die Maschine nicht ausführt |
| `Ebreak` | ein `ebreak`, das keinen Beweis hat |
| `ClockOverflow` | mehr als `2^36 − 1` Zyklen |
| `PublicInputTooLong`, `JournalTooLong` | eine Eingabe oder das Längenwort des Journals beim Exit über 16.380 Byte |
| `DelegationFrame` | ein Frame, für den sein Schaltkreis keinen Witness hat: ein Operand von `MOD_MUL` oder `EC_ADD`, der seinen Modul erreicht oder übersteigt, ein Selektor, der nichts benennt, eine Keccak-Runde über 23, eine SHA-256-Gruppe über 15, eine Poseidon2-Lane, die `p` erreicht oder übersteigt |
| `DelegationFamilyAbsent` | die Nummer einer vom Image nie deklarierten Delegation, auf einem Tracing-Pfad |

## Das ELF wird zurückgewiesen

`artifact-dump`, `host::setup` und die Werkzeuge weisen ein ELF, das der Loader nicht annehmen kann, mit einem `LoaderError` zurück:

| Zurückweisung | Übliche Ursache |
| --- | --- |
| `NotAnElf`, `Truncated` | nicht das ELF des Gastprogramms: eine `.d`-Datei, ein unvollständiger Schreibvorgang |
| `NotRiscV`, `UnsupportedElfType`, `RelocatableElf`, `DynamicElf` | ein Host-Build, eine Objektdatei, ein PIE oder ein dynamisch gelinkter Build |
| `BadSegment`, `NoExecutableSegment`, `EntryNotAnInstruction` | eine bearbeitete `link.ld` oder kein gelinktes `_start` |
| `RvcIllegal`, `InstructionTooLong`, `TextTruncated` | Daten in `.text`, etwa eine Tabelle in von Hand geschriebenem Assembly. Nie das Null-Halbwort, das zu erwarten ist |

## Das Programm lässt sich nicht registrieren

Das ELF lädt, aber das Programm lässt sich nicht in eine Konfiguration dekodieren:

| Zurückweisung | Ursache und Abhilfe |
| --- | --- |
| `Not all opcodes supported: pc=…` | ein Wort außerhalb von RV32IMA irgendwo im ausführbaren Code, erreichbar oder nicht, etwa ein CSR-Zugriff oder `fence.i` in Assembly. Entfernen Sie es |
| `TableTooShort` | Code jenseits der Tabellenreichweite einer Familie. Erhöhen Sie die Höhe dieser Familie: `2^22` reicht für 7,9375 MiB Code |
| `ProgramTooLarge` | das Image überschreitet `bytecode_size_words`, standardmäßig 4 MiB. Erhöhen Sie die Obergrenze in `ProgramParams` |
| `ImageOutsideWindow` | ein in der Datei enthaltenes Byte liegt bei Ihrer Fensterhöhe jenseits von RAM-Fenster 0. Erhöhen Sie die Fensterhöhe |
| `HeightNotOnMenu` | eine Höhe, die nicht `2^8`, `2^12`, `2^16`, `2^18`, `2^20` oder `2^22` ist |
| `UnknownDelegation` | das Image deklariert eine Delegationsnummer, auf die keine Familie antwortet |

Ein Schlüssel lässt sich außerdem nicht bauen, wenn eine Familie, die das Programm verwendet, unter ihre Untergrenze gesetzt ist, `2^20` für eine Befehlsfamilie und `2^16` für die RAM-Fensterfamilien, weil dort kein Schaltkreis existiert.

## Der Prover schlägt fehl

Ein ehrlicher Prover, der beweist, was der Emulator ausgeführt hat, schlägt nicht fehl; ein Fehlschlag deutet also auf eine Eingabe hin, die er nicht hätte annehmen dürfen, oder auf einen Bug. Zwei Fälle machen den Großteil aus:

- **Ein Aufruf ohne Beweis.** Ein Systemaufruf außerhalb von `EXIT` und den Delegationen, den eine Bibliothek für Daten des Hosts abgesetzt hat, erhält `-ENOSYS` als Antwort, und der Lauf geht weiter, aber das Befüllen im Prover weist diese Zeile zurück und nennt den Zyklus. Suchen Sie die Abhängigkeit, die nach Zufall oder Zeit fragt.
- **Speicher erschöpft.** Der Prozess wird beendet, während Shards in Bearbeitung sind. Verringern Sie das dritte Argument von `host::prove` oder die Höhen.

Für alles andere bauen Sie mit dem Debug-Log des Provers neu und führen erneut aus:

```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` nennt das erste fehlschlagende Gate der Zeile und den Wert jedes Operanden. [Das Debug-Log](https://apogee.gweb3networks.com/docs/reference/tools#s3) listet jeden Marker auf.

## Die Verifikation schlägt fehl

`verify_shard` und `verify_block` geben einen `VerifyError` zurück, dessen Klasse angibt, was fehlgeschlagen ist:

| Klasse | Bedeutung |
| --- | --- |
| `Statement` | die Aussage passt nicht zum Schlüssel: Shard-Zahlen, Fensterregeln, Nutzlastlängen, Listen oder der globale Digest, mit dem der Beweis initialisiert wurde |
| `Malformed` | die Form des Beweises ist nicht die seines Schaltkreises: Anzahl der Commitments, Ausgaben, Runden oder Behauptungen |
| `Constraint { layer }` | ein Gate ist verletzt, oder der Sumcheck einer Schicht schlägt fehl |
| `Lookup { channel }` | ein nachgeschlagenes Tupel steht in keiner Zeile seiner Tabelle |
| `MemoryArgument` | die Lese- und die Schreib-Multimenge gleichen sich nicht ab, oder ein öffentliches Fenster enthält nicht die Bytes der Aussage |
| `Opening` | eine Öffnung eines Commitments schlägt fehl |

Wenn Sie den Beweis mit dem eigenen Prover von Apogee aus einer Ausführung erstellt haben, die der Emulator akzeptiert hat, bedeutet ein Verifikationsfehler, dass Verifier und Prover sich über das Programm uneinig sind: Prüfen Sie, dass Sie den Schlüssel laden, unter dem der Beweis erstellt wurde, mit denselben Höhen und über derselben Zeremonie.

## Abweichende Identität

Die Identität, die Sie berechnet haben, weicht von der erwarteten ab:

- **Der Build einer anderen Maschine.** Das ELF bettet absolute Pfade ein; ein Neubau an anderer Stelle ist also ein anderes Image. Vergleichen Sie mit dem ELF, das bewiesen wurde, nicht mit einem frischen Build.
- **Andere Höhen.** Jede Höhe ist in die Identität eingebunden. `artifact-dump tables` meldet die Identität bei den Standardhöhen; Ihr Setup verwendet möglicherweise andere.
- **Eine andere Zeremonie.** Eine Powers-of-Tau-Datei von Hermez hat ein anderes `τ`; jedes Commitment ist also anders. Prüfen Sie das `[τ]_1` der Datei gegen [das der Zeremonie](https://apogee.gweb3networks.com/docs/launch/setup#ceremony).
