|
fighting the "my" pointer
#395538
02/24/12 15:00
02/24/12 15:00
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
OP
Expert
|
OP
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
From what I understand, the my pointer works in the following way: When an entity is removed, all functions in which the "my" pointer points to this entity are stopped. At random intervals, however, I get a "Error E1513: Script crash in shieldEffectEnt: se5". This means that the line if(my) ent_remove(my); crashes. But why? Even if some other function removes the my entity, then this function should be terminated, right? And if no other function deletes the my pointer, then why does the ent_remove call crash?
void shieldEffectEnt()
{
sys_marker("se0");
set(my,PASSABLE);
vec_set(my.pan,vector(you.lastHitPan, you.lastHitTilt,0));
my.flags2 |= UNTOUCHABLE;
my_playsound(my,shieldHitOGG, volumeMain*volumeFX*500*soundBrightFlash);
my.parent = you;
sc_ent_shieldImpact(my, getShieldEffectColor(you.shieldEffectType), 15, 1);
var timePassed = 0;
while(my != NULL && you != NULL && timePassed < 8)
{
sys_marker("se3");
timePassed += time_frame;
vec_set(my.x, you.x);
sys_marker("se4");
wait(1);
}
sys_marker("se5");
if(my) ent_remove(my); //will also stop sc_ent_shieldImpact
sys_marker("se6");
}
Edit: I just checked. The "my" pointer is not changed during the lifetime of the function. Or, more precisely, I logged the my pointer just before sys_marker("se0"); and before sys_marker("se5");. In both cases, it spat out the exact same value for the pointer. Still, I get the exact same crash.
Last edited by Germanunkol; 02/24/12 15:23.
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: fighting the "my" pointer
[Re: Ch40zzC0d3r]
#395543
02/24/12 15:40
02/24/12 15:40
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Just for the sake of curiosity, try this mod...
...
sys_marker("se5");
if(my)
{
sys_marker("se6");
ent_remove(my); //will also stop sc_ent_shieldImpact
}
sys_marker("se8");
Cause Im curious if its failing on the ent_remove, or the IF. Then try...
...
sys_marker("se5");
if(my)
{
sys_marker("se6");
wait(1);
sys_marker("se7");
ent_remove(my); //will also stop sc_ent_shieldImpact
}
sys_marker("se8");
Just to see if a wait makes a difference... (I think unlikely). To be honest, its a REALLY strange error... Unless, maybe, this function is being called as an event from somewhere... And is maybe generating an incorrect error message...
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: fighting the "my" pointer
[Re: EvilSOB]
#395547
02/24/12 15:49
02/24/12 15:49
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
I want to guess too, I want to guess too! Okay, so I doubt that the if crashes like EvilSOB guessed, just checking if a pointer evaluates to true can't crash unless you managed to free some memory that you shouldn't have access to in the first place. But, here is my guess; The feature you want to use requires the help of the scheduler, the scheduler only kicks in if you enter it with a wait() call but you function might not even call it once, for example if you is NULL and timePassed is greater or equal to 8. I don't know how you call this function, but is it possible that you manage to ent_remove() my before you enter it? If yes, you could set my explicitly to NULL after your ent_remove(my) to make sure that you don't work with the dead entity.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: fighting the "my" pointer
[Re: WretchedSid]
#395548
02/24/12 16:07
02/24/12 16:07
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Ahh yes! That does sound more logical, and fits the symptoms pretty well.
'shieldEffectEnt' is being called with a dead, but still warm, MY pointer. So the my pointer is 'dead' but still contains a pointer to the 'corpse'. So when the loop eventually falls through to the ent_remove, then it crashes.
And because 'shieldEffectEnt' was not yet running when that MY was originally removed, then that original ent_remove couldnt possibly kill this function.
Clever...
But ... how do we protect against it happening? I cant see any way to do it from in here... we need some protection in the calling function methinks...
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: fighting the "my" pointer
[Re: EvilSOB]
#395551
02/24/12 16:32
02/24/12 16:32
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
You could create a shim for ent_remove...
void _ent_remove_stub(ENTITY *);
void _ent_remove_stub_init()
{
_ent_remove_stub = ent_remove;
}
#define ent_remove(ent) do {if(ent == my){_ent_remove_stub(ent); my = NULL; return;} _ent_remove_stub(ent);} while(0)
Dirty? Check Untested? Check Works? Maybe You just need to call _ent_remove_stub_init() somewhere, possibly before calling ent_remove the first time =/ The intention is to set my to NULL and to leave the function/action before doing any harm with the now dead my ENTITY. You could make it less risky by just calling the define ent_remove_save() or so, but then you had to search and replace code and we are all lazy coders, aren't we? ^^
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: fighting the "my" pointer
[Re: EvilSOB]
#395553
02/24/12 16:33
02/24/12 16:33
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
OP
Expert
|
OP
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
Wow, lots of replies, thanks guys. In the meantime I have tried to update all of my scripts using some c++ code to automatically modify them. My goal was to make every ent_remove call that there is in the script log into a file in case it deletes the entity that my in this function points to. That doesn't work though, for some reason I suddenly get messages saying entities have "Invalid MDL format". Which is absolutely weird, but it might have something to do with the fact that this logging loads and closes the file way too many times. Ch40zzC0d3r, I don't think a wait will do the trick. But I can try. I can also try out EvilSOB's ideas, but I have to leave soon and it will take some time before I can get to it. JustSid, your idea does sound the most reasonable to me as well. The problem ist that I can rule this out (unless I'm making a mistake here somewhere, so please correct me if I'm wrong!) Just after posting above, I added two logging functions, before the sys_marker("se0") and before the sys_marker("se5"). In both cases, I log a random value as an "ID", that stays the same throughout the function, to make sure both logging functions use the same ID (so I can find which two log-entries belong to the same instance of the function). Then I log the value of the my pointer. I get the following log (this is only a small part of it): .. .. .. .. .. .. !(debug) shieldEffectEnt: 620.665039 .. .. .. .. .. .. !(debug) my:: 48265.832031 .. .. .. .. .. .. !(debug) shieldEffectEnt: 2292.555664 .. .. .. .. .. .. !(debug) my:: 48231.097656 .. .. .. .. .. .. !(debug) shieldEffectEnt: 8088.179688 .. .. .. .. .. .. !(debug) my:: 48280.527344 .. .. .. .. .. .. !(debug) shieldEffectEnt: 5034.590820 .. .. .. .. .. .. !(debug) my:: 48132.238281 .. .. .. .. .. .. !(debug) shieldEffectEnt: 620.665039 .. .. .. .. .. .. !(debug) my:: 48265.832031 As you can see, shieldEffectEnt 620 has the same value when called at the beginning of the function and when called at the end. This means the my pointer does not change. But what you also see is that there's log entries in between the two. That means that I got to the wait somehow, because otherwise the other functions would not have been able to run between the first 620 log entry and the second one. Here's the code:
void shieldEffectEnt()
{
var randID = random(9999);
logNewValue("shieldEffectEnt", randID, debugLog, OFF);
logNewValue("my:", my, debugLog, OFF);
sys_marker("se0");
set(my,PASSABLE);
vec_set(my.pan,vector(you.lastHitPan, you.lastHitTilt,0));
my.flags2 |= UNTOUCHABLE;
my_playsound(my,shieldHitOGG, volumeMain*volumeFX*500*soundBrightFlash);
sys_marker("se1");
my.parent = you;
sc_ent_shieldImpact(my, getShieldEffectColor(you.shieldEffectType), 15, 1);
var timePassed = 0;
while(my != NULL && you != NULL && timePassed < 8)
{
sys_marker("se3");
timePassed += time_frame;
vec_set(my.x, you.x);
sys_marker("se4");
wait(1);
}
sys_marker("se2");
logNewValue("shieldEffectEnt", randID, debugLog, OFF);
logNewValue("my:", my, debugLog, OFF);
sys_marker("se5");
if(my) ent_remove(my); //will also stop sc_ent_shieldImpact
sys_marker("se6");
}
The only way that shieldEffectEnt is called is this way: ent_create(sc_shieldMDL,my.x,shieldEffectEnt); That means it will never be called with a broken my pointer, unless ent_create fails, in which case shieldEffectEnt should not be called at all. Edit: I have tried with a wait(1); before the ent_remove. It changes nothing, same crash in "se5". These are the last lines of the log before the crash:
.. .. .. .. .. .. !(debug) shieldEffectEnt: 2816.185547
.. .. .. .. .. .. !(debug) my:: 48288.542969
rkt time: 4648.295898
.. .. .. .. .. .. !(debug) shieldEffectEnt: 2521.109375
.. .. .. .. .. .. !(debug) my:: 48313.925781
.. .. .. .. .. .. !(debug) shieldEffectEnt: 4278.441406
.. .. .. .. .. .. !(debug) my:: 48235.105469
rkt time: 4649.435547
.. .. .. .. .. .. !(debug) shieldEffectEnt: 7803.479492
.. .. .. .. .. .. !(debug) my:: 48406.105469
rkt time: 4650.536133
rkt time: 4651.131836
rkt time: 4652.229492
rkt time: 4652.229492
.. .. .. .. .. .. !(debug) shieldEffectEnt: 5514.889648
.. .. .. .. .. .. !(debug) my:: 48591.800781
rkt time: 4652.820313
.. .. .. .. .. .. !(debug) shieldEffectEnt: 2756.376953
.. .. .. .. .. .. !(debug) my:: 48450.191406
.. .. .. .. .. .. !(debug) shieldEffectEnt: 5325.700195
.. .. .. .. .. .. !(debug) my:: 48590.464844
.. .. .. .. .. .. !(debug) shieldEffectEnt: 9378.639648
.. .. .. .. .. .. !(debug) my:: 48233.769531
.. .. .. .. .. .. !(debug) shieldEffectEnt: 3958.649414
.. .. .. .. .. .. !(debug) my:: 48291.214844
.. .. .. .. .. .. !(debug) shieldEffectEnt: 2816.185547
.. .. .. .. .. .. !(debug) my:: 48288.542969
Last edited by Germanunkol; 02/24/12 16:55.
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: fighting the "my" pointer
[Re: Germanunkol]
#395920
02/29/12 10:02
02/29/12 10:02
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
OP
Expert
|
OP
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
Update: EvilSob, I tried your code examples. this crashes in se7:
void shieldEffectEnt()
{
var randID = random(9999);
logNewValue("shieldEffectEnt", randID, debugLog, OFF);
logNewValue("my:", my, debugLog, OFF);
sys_marker("se0");
set(my,PASSABLE);
vec_set(my.pan,vector(you.lastHitPan, you.lastHitTilt,0));
my.flags2 |= UNTOUCHABLE;
my_playsound(my,shieldHitOGG, volumeMain*volumeFX*500*soundBrightFlash);
sys_marker("se1");
my.parent = you;
sc_ent_shieldImpact(my, getShieldEffectColor(you.shieldEffectType), 15, 1);
var timePassed = 0;
while(my != NULL && you != NULL && timePassed < 8)
{
sys_marker("se3");
timePassed += time_frame;
vec_set(my.x, you.x);
sys_marker("se4");
wait(1);
}
sys_marker("se2");
logNewValue("shieldEffectEnt", randID, debugLog, OFF);
logNewValue("my:", my, debugLog, OFF);
sys_marker("se5");
if(my)
{
sys_marker("se6");
wait(1);
sys_marker("se7");
ent_remove(my); //will also stop sc_ent_shieldImpact
}
sys_marker("se8");
}
Last few lines of the log are: .. .. .. .. .. .. !(debug) shieldEffectEnt: 6173.087891 .. .. .. .. .. .. !(debug) my:: 48872.683594 .. .. .. .. .. .. !(debug) shieldEffectEnt: 4812.445313 .. .. .. .. .. .. !(debug) my:: 49047.691406.. .. .. .. .. .. !(debug) shieldEffectEnt: 5065.715820 .. .. .. .. .. .. !(debug) my:: 48610.839844 .. .. .. .. .. .. !(debug) recreate started .. .. .. .. .. .. !(debug) shieldEffectEnt: 3333.101563 .. .. .. .. .. .. !(debug) my:: 48711.035156 .. .. .. .. .. .. !(debug) shieldEffectEnt: 3002.628906 .. .. .. .. .. .. !(debug) my:: 48839.285156 .. .. .. .. .. .. !(debug) shieldEffectEnt: 6456.873047 .. .. .. .. .. .. !(debug) my:: 48880.699219 .. .. .. .. .. .. !(debug) shieldEffectEnt: 2788.721680 .. .. .. .. .. .. !(debug) my:: 48845.964844 .. .. .. .. .. .. !(debug) shieldEffectEnt: 7676.539063 .. .. .. .. .. .. !(debug) my:: 48482.589844 .. .. .. .. .. .. !(debug) shieldEffectEnt: 4812.445313 .. .. .. .. .. .. !(debug) my:: 49047.691406Edit: funny thing, I get the same error in another function, this causes a script crash in p16:
if(my != NULL && levelEnded == OFF && disconnectedFromServer == OFF)
{
sys_marker("p15");
if(enet_ent_globpointer(my) != -1)
{
sys_marker("p16");
// logNewMessage("p14", quickDebugLog, OFF);
enet_ent_remove(enet_ent_globpointer(my));
}
}
Last edited by Germanunkol; 02/29/12 10:58.
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: fighting the "my" pointer
[Re: Germanunkol]
#395925
02/29/12 11:51
02/29/12 11:51
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Hmmm... OK, for starters, try modding my snippet and try again. You should be able to see where this fits...
...
if(my)
{
sys_marker("se6");
void* temp_data=NULL; temp_data = ent_getmesh(me,0,0);
if(temp_data==NULL) { error("ME has no mesh...dead?"); }
sys_marker("se7");
BMAP* tmp_bmap=NULL; tmp_bmap = ent_getskin(me,1);
if(temp_bmap==NULL) { error("ME has no skin...dead?"); }
sys_marker("se8");
ent_remove(my); //will also stop sc_ent_shieldImpact
}
sys_marker("se9");
}
Now, as for the error occuring in enet_ent_remove() as well... interesting. We are going to need an enet guru for help on this, cause Ive never used it. But is it POSSIBLE that the MY causing the error (in the first problem) is somehow being removed by ENet itself? That is, do you ever give 'this' entity to enet for any reason? Because, at a GUESS, it may be that if ENet removes an entity, then MAYBE the acknex scheduler doesnt know that it needs to shut down any actions used by that entity... Just a hunch... Let us know how the first test goes...
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: fighting the "my" pointer
[Re: EvilSOB]
#395927
02/29/12 13:02
02/29/12 13:02
|
Joined: Oct 2011
Posts: 1,082 Germany
Ch40zzC0d3r
Serious User
|
Serious User
Joined: Oct 2011
Posts: 1,082
Germany
|
Äh what? if(enet_ent_globpointer(my) != -1) ? When its 0 there is no pointer too....
And there is no enet_ent_reove function btw... Its called enet_clent_remove and enet_svent_remove. Update ur anet version!
Last edited by Ch40zzC0d3r; 02/29/12 13:03.
|
|
|
|