Help debugging please.
Moderator: InsideQC Admins
6 posts
• Page 1 of 1
Help debugging please.
hey there, recently I have been having some problems with a pathfinding code that I have made (you know, navigate waypoints around the map to get to a certain object), but the problem is is that I get a stack_overflow error
obviously I know stack_overflow happens when a function is called too much.
now, I have a dilema
when it gives the crash error, it gives it like this...
and it continues giving the
"^7 ai.qc : wayenqueB : statement 194" honestly for another 500 lines.
and ends with...
anyways, yes, I know that wayenqueB calls itself
I am FULLY aware of that.
but I have set very specific conditions on when to loop, and when to not loop.
also, another thing that bugs me, is I have made the function bprint a special string so I can tell how many times wayenqueB is being run, however, according to the bprint, it could be running as little as 4 times, but the error STILL gives me like 500 lines of
the ^7 wayenqueB : statement 49 error...
so what's right?
is it really being run 500 times?
or does the error just show what functions run which?
(not which function called which function at the time of the crash)
bonus question: is there any way to correlate statement #s to lines of code?
I really need to figure this out :\
I can provide the function if necessary.[/quote]
obviously I know stack_overflow happens when a function is called too much.
now, I have a dilema
when it gives the crash error, it gives it like this...
- Code: Select all
^7SZ_GetSpace: overflow
^7SZ_GetSpace: overflow
^7SZ_GetSpace: overflow
^7Host_Error: stack overflow
^7QuakeC crash report for server:
^7s1681: ^6FIELD_ENT way (=entity 54), owner2, GLOBAL2104
^7s1682: ^6FIELD_ENT way (=entity 54), owner3, GLOBAL2105
^7s1683: ^6FIELD_ENT way (=entity 54), owner4, GLOBAL2106
^7s1684: STORE_V GLOBAL2103, GLOBAL4
^7s1685: STORE_V GLOBAL2104, GLOBAL7
^7s1686: STORE_V GLOBAL2105, GLOBAL10
^7s1687: STORE_V GLOBAL2106, GLOBAL13
^7s1688: ^3CALL4 find_best (=find_best())
^7 ai.qc : wayenqueB : statement 20
^7 ai.qc : wayenqueB : statement 20
^7 ai.qc : wayenqueB : statement 194
^7 ai.qc : wayenqueB : statement 194
^7 ai.qc : wayenqueB : statement 194
and it continues giving the
"^7 ai.qc : wayenqueB : statement 194" honestly for another 500 lines.
and ends with...
- Code: Select all
^7 ai.qc : wayenqueB : statement 126
^7 ai.qc : wayenqueB : statement 93
^7 ai.qc : wayenqueB : statement 194
^7 ai.qc : wayenqueB : statement 60
^7 ai.qc : wayenqueB : statement 60
^7 ai.qc : gotoway : statement 168
^7 ai.qc : zombie_walk : statement 42
^7 knight.qc : knight_run1 : statement 2
^7 knight.qc : knight_walk : statement 30
anyways, yes, I know that wayenqueB calls itself
I am FULLY aware of that.
but I have set very specific conditions on when to loop, and when to not loop.
also, another thing that bugs me, is I have made the function bprint a special string so I can tell how many times wayenqueB is being run, however, according to the bprint, it could be running as little as 4 times, but the error STILL gives me like 500 lines of
the ^7 wayenqueB : statement 49 error...
so what's right?
is it really being run 500 times?
or does the error just show what functions run which?
(not which function called which function at the time of the crash)
bonus question: is there any way to correlate statement #s to lines of code?
I really need to figure this out :\
I can provide the function if necessary.[/quote]
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it 
-

blubswillrule - Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
recursion: see recursion.
The QCVM has a slight bug in that if you do use recursion, the initial values of local variables are initialised to the value of the previous version of the function (even if you explicitly initialise them yourself in the definition).
In C, you can't assume initial values. Turns out you can't in QC either, not even if it was initialised. Its fine if you don't use recursion.
Setting them to their correct initial value on a statement *after* they are declared works (as that's a regular assignment), just so long as its not the done on the line where it is created. basically if the qcc accepts a formula for the value its okay (meaning its assigned to rather than initialised).
Otherwise you're recursing too often.
if you're using fteqcc to compile, and you're running it in fteqw, set 'developer 1', and use the command 'break wayenqueB'. Get that function executed, Then use f11 to see how the program flows (f3 can be used to inspect vars, f5 will resume running, f9 toggles a breakpoint).
Or just crash it in fteqw and look at the coredump. It should print out the locals and their values if you don't use too many qcc optimisations.
The QCVM has a slight bug in that if you do use recursion, the initial values of local variables are initialised to the value of the previous version of the function (even if you explicitly initialise them yourself in the definition).
In C, you can't assume initial values. Turns out you can't in QC either, not even if it was initialised. Its fine if you don't use recursion.
Setting them to their correct initial value on a statement *after* they are declared works (as that's a regular assignment), just so long as its not the done on the line where it is created. basically if the qcc accepts a formula for the value its okay (meaning its assigned to rather than initialised).
Otherwise you're recursing too often.
if you're using fteqcc to compile, and you're running it in fteqw, set 'developer 1', and use the command 'break wayenqueB'. Get that function executed, Then use f11 to see how the program flows (f3 can be used to inspect vars, f5 will resume running, f9 toggles a breakpoint).
Or just crash it in fteqw and look at the coredump. It should print out the locals and their values if you don't use too many qcc optimisations.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
hmm, that's some interesting stuff.
however, I do believe that I redefine everything in wayenqueB
that's the basic code.
anyways, so what you're saying is, every time I run this function, it's using a previous version of the local variables?
even though I specifically define what the local variables are?
so if I had...
would that always return the same value for stuff?
or would that multiply it by 2 every time it runs the function?
however, I do believe that I redefine everything in wayenqueB
- Code: Select all
void(entity way) wayenqueB =
{
bprint ("wayenque B! \n");
if (way == world)
bprint("waypoint is world!!! \n");
else
bprint("waypoint IS NOT world! \n");
setmodel(way, "progs/radio.mdl");//for being able to see which waypoints are being checked
local entity best1, best2, best3, best4;
find_best(way.owner1, way.owner2, way.owner3, way.owner4);//returns the waypoints links in order of closest to the player + itself, in order of leaast to greatest, and sets them as .sbest1, 2, 3, and 4.
best1 = self.sbest1;
best2 = self.sbest2;
best3 = self.sbest3;
best4 = self.sbest4;
if (best1 != world)
{
bprint("way.owner1 is not world! \n");
if (!(in_list(self, best1)))
{
if (best1 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
best1.owner = way;
tracepath();
return;
}
if(best1 != self.cway)
{
bprint("best1 is not marked! \n");
add_to_list(self, best1);
bprint("smurfb \n");
best1.owner = way;
wayenqueB (best1);
return;
}
}
}
if (best2 != world)
{
bprint("best2 is not world! \n");
if (!(in_list(self, best2)))
{
if (best2 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
best2.owner = way;
tracepath();
return;
}
if(best2 != self.cway)
{
bprint("best2 is not marked! \n");
add_to_list(self, best2);
best2.owner = way;
bprint("smurfc \n");
wayenqueB (best2);
return;
}
}
}
if (best3 != world)
{
bprint("best3 is not world! \n");
if (!(in_list(self, best3)))
{
if (best3 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
best3.owner = way;
tracepath();
return;
}
if(best3 != self.cway)
{
bprint("best3 is not marked! \n");
add_to_list(self, best3);
best3.owner = way;
bprint("smurfd \n");
wayenqueB (best3);
return;
}
}
}
if (best4 != world)
{
bprint("best4 is not world! \n");
if (!(in_list(self, best4)))
{
if (best4 == self.cway)// USED TO BE == SELF.GOALWAY, BUT WE ARE NOW GOING BACKWARDS WITH FINDING THE TREE, IT WILL BE OF HELP TO US LATER!
{
bprint ("we found the zombie's cway with enque B! \n");
best4.owner = way;
tracepath();
return;
}
if(best4 != self.cway)
{
bprint("best4 is not marked! \n");
add_to_list(self, best4);
best4.owner = way;
bprint("smurfe \n");
wayenqueB (best4);
return;
}
}
}
bprint("nothing worked, going backwards! \n");
if (best1 == world || (in_list(self, best1))/*best1.MARK ==TRUE*/)
{
if (best2 == world || (in_list(self, best2))/*best2.MARK == TRUE*/)
{
if (best3 == world || (in_list(self, best3)) /*best3.MARK == TRUE*/)
{
if (best4 == world || (in_list(self, best4))/*best4.MARK == TRUE*/)
{
bprint ("DEAD LINK!, RESTARTING! \n");
if (way.owner != world)
bprint("going backwards... smurff \n");
wayenqueB(way.owner);
return;
}
}
}
}
};
that's the basic code.
anyways, so what you're saying is, every time I run this function, it's using a previous version of the local variables?
even though I specifically define what the local variables are?
so if I had...
- Code: Select all
void() test_stuff =
{
local float stuff;
stuff = stuff * 2;
test_stuff()l
};
would that always return the same value for stuff?
or would that multiply it by 2 every time it runs the function?
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it 
-

blubswillrule - Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
its just the initial values, and you assign to all your locals before use anyway so its not that.
single-step though. probably you're hitting the same node multiple times, or just simply too many nodes.
if its simply too many nodes, use a goto or something instead of recursion+return.
gotos are evil, but whatever.
single-step though. probably you're hitting the same node multiple times, or just simply too many nodes.
if its simply too many nodes, use a goto or something instead of recursion+return.
gotos are evil, but whatever.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
well, I highly doubt that the problem is too many nodes, seeing as only placing 3 will still crash it.
However, it might be hitting the nodes more than once, but I have specifically added in a list of nodes that each ai has so it doesn't check each node more than once.
Although this may not be that smartest thing to do, it runs this whole process every time it hits the next node.
Currently this system works, but only 1 time, it's on the second time that it crashes with this error, EVERY TIME
so basically there could be an ai on the other side of the map... he finds the "path"(although I only make the ai store the next waypoint he has to go to, and once he hits that one, he runs this all again) then he simply goes to the first waypoint in his path, and once he hits the waypoint, it should run this process again, but it crashes with this stack overflow. :\
I would make the ai store the WHOLE path, but the problem with that would be if the player moves, then the ai would go to the area the player used to be, I want the ai to keep up with the player don't I?
However, it might be hitting the nodes more than once, but I have specifically added in a list of nodes that each ai has so it doesn't check each node more than once.
Although this may not be that smartest thing to do, it runs this whole process every time it hits the next node.
Currently this system works, but only 1 time, it's on the second time that it crashes with this error, EVERY TIME
so basically there could be an ai on the other side of the map... he finds the "path"(although I only make the ai store the next waypoint he has to go to, and once he hits that one, he runs this all again) then he simply goes to the first waypoint in his path, and once he hits the waypoint, it should run this process again, but it crashes with this stack overflow. :\
I would make the ai store the WHOLE path, but the problem with that would be if the player moves, then the ai would go to the area the player used to be, I want the ai to keep up with the player don't I?
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it 
-

blubswillrule - Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
problem fixed!
ended up simply redoing the pathfinding code, and now it works
ended up simply redoing the pathfinding code, and now it works
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it 
-

blubswillrule - Posts: 68
- Joined: Mon Oct 04, 2010 9:08 pm
- Location: Lincoln, California
6 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest