Eintragsdetails ansehen
ID | Projekt | Kategorie | Sichtbarkeit | Meldungsdatum | Zuletzt aktualisiert |
---|---|---|---|---|---|
0002123 | Eressea | Magie | öffentlich | 2015-08-02 11:01 | 2015-08-16 20:02 |
Reporter | Enno | Bearbeitung durch | Enno | ||
Priorität | dringend | Schweregrad | Absturz | Reproduzierbar | nicht getestet |
Status | geschlossen | Lösung | erledigt | ||
Produktversion | 3.5 | ||||
Zielversion | 3.5 | Behoben in Version | 3.5 | ||
Zusammenfassung | 0002123: crash in update_gbdream | ||||
Beschreibung | See callstack below. When calling update_gbdream while reading the save file, c->magician may not be set (it gets delayed in curse_read by read_reference), and update_gbdream bombs because mage is a null-pointer. This is currently blocking the next turn, because it fails to read the 939.dat file for E2. | ||||
Schritte zur Reproduktion | call stack: #0 0x00000000004c143c in alliedunit (u=0x0, f2=0x1c26730, mode=16) | ||||
Zusätzliche Informationen | TODO:
| ||||
Partei | 0 | ||||
Spiel | E2 | ||||
Report | 939 | ||||
Ich verstehe das nicht. Dort ist schon auf mage == null getestet, und die lazy Evaluation von C sollte dafür sorgen, dass der hintere Teil des ODER nicht ausgewertet wird, er alliedunit() also nicht aufrufen muss. |
|
regardless of that, update_gbdream makes no sense when it doesn't know the magician, because it needs to call alliedunit() to determine whether the curse is effective. So it's wrong to call it before all the resolve_unit() calls have been made. An assert(c->magician) is the right thing to do here, and then fix the logical error upstream. Which is here: #7 0x00000000004dab1b in readgame (filename=0x1d3e7f8 "939.dat", backup=0) |
|
Das übergeordnete Problem ist, dass faction::max_spelllevel während readgame berechnet wird, und aktualisiert wann immer in Magier eingelesen wurde. Wenn der Magier dabei in einer Region mit gute/schlechte Träume steht, kann sein Talent nicht bestimmt werden, das darf also nicht passieren, ehe resolve() aufgerufen wurde (passiert erst später in readgame). Einfacher Fix ist, max_spelllevel in einem zusätzlichen Pass am Ende von readgame zu berechnen, aber das ist O(Alle Einheiten) komplex. Besser wäre es, das on-demand zu berechnen wenn es gebraucht wird, in einer Getter-Funktion (die es aber noch nicht gibt), und alle Magier der Partei zu durchsuchen, was dann nur O(#f.units) ist. |
|
Hmm. Selbst wenn ich das mache (ich habe erst einmal die schnelle Lösung implementiert), ist immer noch ein curse mit c->magician==null in den Daten. Der hat die ID 652303, mal gucken, warum der nicht resolved wurde... |
|
Der curse ist gar nicht "gbdreams", sondern "holyground", und hat keinen Magier (ist wahrscheinlich tot, aber holyground hält ja ewig). Warum triggert der meine Assertion? |
|
Oh, I see. Der Test auf c->type == gbdream_ct passiert erst in update_gbdream, aber mein Check war vorher. Das ist ja alles verkehrte Welt, der Test sollte vor dem Aufruf schon passieren. |
|
all done, this hotfix will be in version 3.5.4 |
|
new server version 3.5.4 is installed |
|
Änderungsdatum | Benutzername | Feld | Änderung |
---|---|---|---|
2015-08-02 11:01 | Enno | Neuer Eintrag | |
2015-08-02 11:01 | Enno | Status | neu => zugewiesen |
2015-08-02 11:01 | Enno | Bearbeitung durch | => Enno |
2015-08-02 20:59 | Enno | Notiz hinzugefügt: 0005995 | |
2015-08-02 21:15 | Enno | Notiz hinzugefügt: 0005996 | |
2015-08-02 22:01 | Enno | Notiz hinzugefügt: 0005997 | |
2015-08-02 22:07 | Enno | Notiz hinzugefügt: 0005998 | |
2015-08-02 22:11 | Enno | Notiz hinzugefügt: 0005999 | |
2015-08-02 22:12 | Enno | Notiz hinzugefügt: 0006000 | |
2015-08-02 23:17 | Enno | Notiz hinzugefügt: 0006001 | |
2015-08-02 23:23 | Enno | Notiz hinzugefügt: 0006002 | |
2015-08-02 23:23 | Enno | Status | zugewiesen => erledigt |
2015-08-02 23:23 | Enno | Behoben in Version | => 3.5 |
2015-08-02 23:23 | Enno | Lösung | offen => erledigt |
2015-08-16 20:02 | Enno | Status | erledigt => geschlossen |
2022-04-27 17:27 | Enno | Kategorie | ZAUBER => Magie |