View Issue Details

IDProjectCategoryView StatusLast Update
0005270Spring engineAIpublic2018-02-01 18:27
Reporterlamer Assigned To 
PrioritynormalSeveritycrashReproducibilitysometimes
Status resolvedResolutionfixed 
Product Version101.0+git 
Fixed in Version104.0 
Summary0005270: Unit events sent after UnitDestroyed may crash AI
DescriptionIf unit isDead then AI can't do anything about it. So why bother native AIs with false events when there is no unit validation API?
Additional InformationHere is a debug snippet of bad run:
[f=0007989] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_CREATED unitId: 18785
[f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_DESTROYED unitId: 18785
[f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | attackerDestroyedHandler task:N7circuit9CNullTaskE |
[f=0008017] Skirmish AI <Circuit-0.8.3>: 0 | attackerDestroyedHandler task:N7circuit9CIdleTaskE |
[f=0008018] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_FINISHED unitId: 18785
[f=0008022] Skirmish AI <Circuit-0.8.3>: 0 | EVENT_UNIT_CREATED unitId: 29964
[f=0008024] Skirmish AI <Circuit-0.8.3>: 0 | CScheduler::ProcessTasks Repeat EXCEPTION: Error calling method "fight": 18785


EVENT_UNIT_FINISHED for unitId 18785 was sent after EVENT_UNIT_DESTROYED. It is allowed by engine to send FINISHED event before CREATED (when lua instantly changes health to full), thus no way to detect that EVENT_UNIT_FINISHED was an error and that unit can't be actually used.

Consider legacy AIs (KAIK, E323): seems they don't have try-catch blocks for unit commands and are tottally affected by this bug.
TagsNo tags attached.
Checked infolog.txt for Errors

Activities

lamer

2016-06-07 15:09

reporter   ~0016407

Last edited: 2016-06-08 14:11

Hmm, legacy AIs are not affected because only newOO API throws exceptions intentionally.
Should be requalified as major annoying bug (or feature request), not crash.

Edit:
A simple solution that might work is to check isDead before eoh->UnitFinished() (and maybe UnitGiven) call. UnitFinished happens comparatively rare and additional 'if' shouldn't be a performance hog. This will allow to deregister unit on UnitDestroyed event, not register dead unit and thus ignore all other fail Updates or UnitDamaged.

sprung

2017-10-20 13:29

reporter   ~0018538

Fixed https://github.com/spring/spring/commit/6350db5de5c297e170f22efa27600eefc37bde8c

Kloot

2018-02-01 18:27

developer   ~0018764

that commit covers the finished-after-destroyed case, not the (Lua-driven) finished-before-created one.

since in practice the latter is easily handled, this should still be closable.

Issue History

Date Modified Username Field Change
2016-06-07 15:06 lamer New Issue
2016-06-07 15:09 lamer Note Added: 0016407
2016-06-07 22:06 lamer Note Edited: 0016407
2016-06-08 10:17 lamer Note Edited: 0016407
2016-06-08 14:11 lamer Note Edited: 0016407
2017-10-20 13:29 sprung Note Added: 0018538
2018-02-01 18:27 Kloot Status new => resolved
2018-02-01 18:27 Kloot Resolution open => fixed
2018-02-01 18:27 Kloot Fixed in Version => 104.0
2018-02-01 18:27 Kloot Note Added: 0018764