2019-08-24 22:25 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0005270Spring engineAIpublic2018-02-01 18:27
Reporterlamer 
Assigned To 
PrioritynormalSeveritycrashReproducibilitysometimes
StatusresolvedResolutionfixed 
Product Version101.0+git 
Target VersionFixed 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 lua Errors
Attached Files

-Relationships
+Relationships

-Notes

~0016407

lamer (reporter)

Last edited: 2016-06-08 14:11

View 4 revisions

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.

~0018538

sprung (reporter)

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

~0018764

Kloot (developer)

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.
+Notes

-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 View Revisions
2016-06-08 10:17 lamer Note Edited: 0016407 View Revisions
2016-06-08 14:11 lamer Note Edited: 0016407 View Revisions
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
+Issue History