|
Rorso Wizard
Joined: 14 Oct 2000 Posts: 1368
|
Posted: Wed Sep 20, 2006 9:51 am
[1.06] Weird error |
I am working on a script that suddenly started crashing cMUD. The exception message is "Stack frame corrupted" and I haven't been able to really track it down.
What should I do? |
|
|
|
Larkin Wizard
Joined: 25 Mar 2003 Posts: 1113 Location: USA
|
Posted: Wed Sep 20, 2006 4:36 pm |
Send the exception message (and stack info, if possible) to Zugg with the feedback system. If you can grab the compiled version of your script, or at least the part you think is causing the crash, I'm sure that would help, too.
|
|
|
|
Rorso Wizard
Joined: 14 Oct 2000 Posts: 1368
|
Posted: Wed Sep 20, 2006 6:45 pm |
I have uploaded the script to the script library with the name SBPackage. The crash occurs when walking around in the MUD I play with that package active.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Sep 20, 2006 7:21 pm |
It's going to be hard to reproduce something that just happens "walking around in the MUD". I need you to pin down the trigger or script that is causing the problem. Try disabling all your triggers and then re-enable them one by one to determine which one is causing the problem. "Stack frame corrupted" is usually caused by a problem in the parser where something is left on the runtime stack when it shouldn't. Might be a syntax error, but it's something that needs to be fixed. But without the exact trigger that is causing the problem I can't do much.
|
|
|
|
Rorso Wizard
Joined: 14 Oct 2000 Posts: 1368
|
Posted: Wed Sep 20, 2006 8:22 pm |
Zugg wrote: |
It's going to be hard to reproduce something that just happens "walking around in the MUD". I need you to pin down the trigger or script that is causing the problem. Try disabling all your triggers and then re-enable them one by one to determine which one is causing the problem. "Stack frame corrupted" is usually caused by a problem in the parser where something is left on the runtime stack when it shouldn't. Might be a syntax error, but it's something that needs to be fixed. But without the exact trigger that is causing the problem I can't do much. |
I uploaded the script to the library, SBPackage. The error *seems* to be in this trigger:
#trigger {(*)$} {
#if (%trim( %1)="+---------+") {#noop} {
#noop
#var room.desc %concat( @room.desc, %trimleft( "%1%crlf"))
}
#math descLines @descLines+1
#if (@descLines>=20) {
#echo done with overflow part
#t- overflowPart
}
}
The trigger resides in the class "overflowPart". Commenting out the #var line seems to remove the bug, although the syntax checker does not report about invalid syntax. |
|
|
|
Rorso Wizard
Joined: 14 Oct 2000 Posts: 1368
|
Posted: Wed Sep 20, 2006 8:42 pm |
After working on this some more I have managed to reduce the script to an alias:
#alias test {
#noop
}
> test hello
crash |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Sep 20, 2006 9:58 pm |
Verified. Thanks for narrowing down the alias. I have no idea why something this simple is crashing, but it's a lot easier than trying to figure out a complex script. Should be easy to fix I hope.
|
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Sep 20, 2006 11:02 pm |
That reminds me of one of the first crashes I reported. I think it was in fact just a simple #NOOP by iteself from the command line. I will try to check through the forums, but I doubt it will give you any more useful information than the date. Perhaps you should add some forms of #NOOP to your test script.
Edit:
Found the old topic. I had evidently posted about it back in 1.01, then reconfirmed it for 1.02 and I recall something in the version history where it was corrected subsequent to that. In any case the link to the original topic: http://forums.zuggsoft.com/phpbb/viewtopic.php?t=23948
Further Edit: The version history lists 1.03 as having corrected this. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Sep 21, 2006 6:59 pm |
Yeah, #NOOP still works just fine on the command line, and my test script already has a #NOOP in it. It's something new about #noop within an Alias. I'll be looking into the code for this later today and will let you know what I find.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Sep 21, 2006 8:02 pm |
OK, I found the bug. It was obscure, but also pretty generic and might have been effecting other scripts.
The issue was that #NOOP doesn't actually do "nothing". If you give #NOOP any arguments, they get evaluated. #NOOP used to be used in zMUD for executing COM stuff. So, the implementation of #NOOP causes it to parse it's arguments as expressions. But the routine in CMUD for evaluating an expression was doing something like this:
Code: |
ParseExpression( Arguments)
if SP > 0 then Result := PopValue
else Result := nil; |
where SP is the stack pointer. This makes sense at first glance...evaluate the expression and if there is something left on the stack, return it as the result, otherwise return nil.
The problem in this case what that when you executed the alias "test hello", then "hello" is placed on the stack. And when it gets to the #NOOP, the Arguments for #NOOP are empty, but because "hello" is on the stack, it gets returned as the result of the #NOOP call. Then, when it gets back to the alias, the "hello" argument is gone, so we get a corrupted stack frame error.
The correct code was something more like this:
Code: |
LastSP := SP;
ParseExpression( Arguments)
if SP > LastSP then Result := PopValue
else Result := nil; |
and that fixed the problem.
So, this might have been the cause of various other wierd "stack frame corrupted" errors. |
|
|
|
Rorso Wizard
Joined: 14 Oct 2000 Posts: 1368
|
Posted: Thu Sep 21, 2006 8:27 pm |
Ouch posting "secret code" :-). I hope you don't mind me getting inspired by this(I am a parsing addict :P).
Why don't you simply let ParseExpression return the result? Then you wouldn't need to check the stack pointer. That is instead of letting the caller handle the stack you give that work to the callee. E.g:
Result := ParseExpression(Arguments)
That's usually what I do when I parse expressions. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Sep 21, 2006 9:08 pm |
See, that's the problem with posting "secret code" :) What I posted isn't the real code...it's pseudo code. The routine that I was showing really *is* the ParseExpression routine, and instead of ParseExpression it's really calling the code executer. In other words, it has the compiled code for the expression, so it passes it to the execution module. The execution module just executes the code and has nothing to do with returning a value. So it's up to the routine that I posted to look at the stack and determine what to return.
I was just trying to simplify the code to make a point. |
|
|
|
|
|