Code concurrence problem with Timer and None check

Discussions about Coding and Scripting

Code concurrence problem with Timer and None check

Postby PrinceOfFunky » Wed Sep 28, 2016 5:25 am

I have this check inside Timer function (Timer is set to 0.01, but this problem occurs with a low rate too):
Code: Select all
if (Owner != none) {
         Log(0@Owner);
         SetLocation(Owner.Location);
         SetRotation(Owner.Rotation);
         Log(1@Owner);

These are the logs when a pawn dies and becomes None:
Code: Select all
ScriptLog: 0 Autoplay.TMale0
ScriptWarning: ...Timer:003B) Accessed None
ScriptLog: 1 None

The code is longer than it, there are many instructions that need the pawn to not to be None. Should I seriously need to do the check on every line that requires the Owner?
Image
User avatar
PrinceOfFunky
Godlike
 
Posts: 1020
Joined: Mon Aug 31, 2015 10:31 pm

Re: Code concurrence problem with Timer and None check

Postby Higor » Wed Sep 28, 2016 5:35 am

In UT's native c++ the game would insta-GPF, yes, you do need sanity checks when there's uncertainty that a reference will remain the same.
Higor
Godlike
 
Posts: 1716
Joined: Sun Mar 04, 2012 6:47 pm

Re: Code concurrence problem with Timer and None check

Postby Barbie » Wed Sep 28, 2016 6:08 am

Does this mean that during Timer() execution other code is running that might change the references? AFAIK this can happen only in latent functions or multi threaded code.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1648
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Code concurrence problem with Timer and None check

Postby sektor2111 » Wed Sep 28, 2016 6:09 am

PrinceOfFunky wrote:These are the logs when a pawn dies and becomes None:
And then this thing will lose owner (I'm guessing) and then it might be going in destruction being NONE itself and without owner. And error is probably similar to GuidedWarshell problem when it's still rendering in Deletion process... Keep in mind that I have solved DynAI mod crash by adding a stupid check like this <If (Something != None && !Something.bDeleteMe)> and was the only way to not crash by trying to setup a thing which did not lived any longer (for some reason of that map).
Last edited by sektor2111 on Wed Sep 28, 2016 6:17 am, edited 3 times in total.
User avatar
sektor2111
Godlike
 
Posts: 3905
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Code concurrence problem with Timer and None check

Postby PrinceOfFunky » Wed Sep 28, 2016 6:10 am

Higor wrote:In UT's native c++ the game would insta-GPF, yes, you do need sanity checks when there's uncertainty that a reference will remain the same.

So it is a prevention, well, thanks for the explanation :)
(To your knowledge, is this instantaneous prevention common in many softwares, other than UT?)
Image
User avatar
PrinceOfFunky
Godlike
 
Posts: 1020
Joined: Mon Aug 31, 2015 10:31 pm

Re: Code concurrence problem with Timer and None check

Postby Higor » Wed Sep 28, 2016 6:49 am

As a matter of fact, the ONLY reason your reference is actually being set to none is because some other code in the same thread the game is running has nulled it.

I said it would GPF is you attempted to operate it on c++ without a sanity check, nothing more.
If this 'other code' wasn't setting your reference to none, even the unrealscript counterpart would GPF.

If you deallocate memory, any pointers to that memory region won't be nulled out.
So when memory has to be deallocated, either set the pointers to NULL (before, during or after deallocation) or simply destroy the pointer variables as well.


The game automatically deallocates actors after you pile up at least 256 (i think) destroyed actors and this only happens between ticks, not in the middle of it.
The process consists on running through the entire actor list, looping through Object/Actor variable types (defined in unrealscript), evaluating that there's a pointer to an actor and then seeing if this actor has bDeleteMe=True
If this actor has bDeleteMe=True, then the pointer is nulled (set=none).
Once all pointers to destoyed actors are nulled, the game will free up the object table and start deallocating memory.

Also, never, ever reference actors from outside the level unless you know how to prevent the garbage collector from crashing, or you know how to detect level switches before attempting to access an actor in a level that no longer exists.
Horrible examples of this is the Nexgen controller that references Nexgen actors from it's UWindow interface.
Another horrible example is ScriptedTexture class, in some cases a bit of mishandling will crash the game if the actor in charge of controlling a texture is destroyed and the NotifyActor variable isn't nulled out before level switch.
Higor
Godlike
 
Posts: 1716
Joined: Sun Mar 04, 2012 6:47 pm

Re: Code concurrence problem with Timer and None check

Postby sektor2111 » Wed Sep 28, 2016 4:58 pm

Info saved.
As another matter of fact I'll show you some of my crash code NONE related and... solution. It's a function called in PreBeginPlay
Code: Select all
         Dt = Spawn( class'DecoTest',Pn,,Pn.Location+Vect(0,0,1) );
         if ( Dt != None )
         {
//            log ( Self@"spawned"@Dt@"addressing to check"@Pn );
            if ( Dt.Location.X == Pn.Location.X
               && Dt.Location.Y == Pn.Location.Y
                  && ( Dt.Location.Z - Pn.Location.Z == 1)
                     && !Dt.bDeleteMe ) //02-16-2016 #1 #2 - Now is no longer crashing
            {
//               log (Dt@"is good...");
               Dt.bHaveAGood = True; //#1 Accessed None - it is just in deletion process right after spawn for some reason, hell knows...
               Dt.Tag = 'MeMoving'; //#2 The same crap
               NumOps++;
            }
In previous session it crashed at some strange map without deletion check but... It was initially <!= None>. At this time is part of my playground with no crashes using snippet above.
User avatar
sektor2111
Godlike
 
Posts: 3905
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Code concurrence problem with Timer and None check

Postby Wormbo » Wed Sep 28, 2016 8:08 pm

Barbie wrote:Does this mean that during Timer() execution other code is running that might change the references? AFAIK this can happen only in latent functions or multi threaded code.

That particular Timer code actually calls that other code indirectly through SetLocation. Changing the location of an actor can immediately cause multiple events to happen, which in this case either just changed the Owner or even destroyed it. The following call to SetRotation then attempted to access a property of the now-empty Owner variable, causing the Accessed None error.
User avatar
Wormbo
Adept
 
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm

Re: Code concurrence problem with Timer and None check

Postby PrinceOfFunky » Thu Sep 29, 2016 2:34 am

Wormbo wrote:That particular Timer code actually calls that other code indirectly through SetLocation.

To me, it occurred using:
- SetLocation()
- SetRotation()
- Casting.
- IsA()
- Variables assignments.
- Variables retrievings.
- getStateName()

Higor wrote:The game automatically deallocates actors after you pile up at least 256 (i think) destroyed actors and this only happens between ticks, not in the middle of it.

The same code used into "Tick()" function, gave the same Accessed None's.
Image
User avatar
PrinceOfFunky
Godlike
 
Posts: 1020
Joined: Mon Aug 31, 2015 10:31 pm


Return to Coding, Scripting

Who is online

Users browsing this forum: No registered users and 2 guests