View previous topic :: View next topic |
Author |
Message |
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Mon Jan 14, 2013 4:09 am Post subject: stack woes |
|
|
I fail to understand what is happening here. Whilst trying to track down an apparent Frame overflow in a prog that is about 3000 lines long, I have narrowed at least one overflow to one line. The test program below, consistently gives me a stack error immediately after the open com. I'm sure that there is enough stack!. Code: |
Const Stack_dbg = 1 'enables stack checking if set
$regfile = "m1284pdef.dat"
$crystal = 10000000
$framesize = 500 ' Located at top of 16k of SRAM
$hwstack = 300 '
$swstack = 300 '
Disable Jtag
Dim Error As Byte
Declare Sub Stack_chk(byval Routine As Byte)
'-------------------------------------------------------------------------------
'Open a software UART TRANSMIT channel for debug dB9
Open "comc.3:9600,8,n,1" For Output As #1
#if Stack_dbg = 1 : Call Stack_chk(250) : #endif
Print #1 , "Hello cruel world"
Stop
'_____________________________________________________
#if Stack_dbg = 1
Sub Stack_chk(byval Routine As Byte)
Error = 0
Stcheck
If Error > 0 Then
Print #1 , ">>>>Stack err " ; Error ; " in " ; Routine
End If
Error = 0
End Sub
#endif
'err 1 = hw stack grows down into soft stack space =not enough hw stack
'err2 = is soft stack space grows down into frame space =not enough soft stack
'err3 if frame space grows up into soft stack space = not enough frame
'********************************************************************************* |
When I run this it consistently gives me Quote: |
>>>>Stack err 3 in 250
Hello cruel world |
Some time later:
Since the above post earlier today, I have spent several fruitless hours trying to sort out this stack problem ( or not). My prog has only 3 functions, where variable are passed, and there is only one var per function. There are no local variables. I do have a large number of print statements, to the debug port, to a second software uart and to both hardware uarts. However even if I set the Frame to 2000 bytes, I get continuous Frame errors. Commenting out ALL of my print #1 statements to the debug port makes no different at all. A second problem seems to be that if there is a frame error at some point in the program, every time I call ST_ceck function, subsequently to the first overflow, its still there, and so the indication as to the location of the overflow is almost impossible to pin down as to where it actually comes from. For example, in the middle of my program, i created a do loop, with nothing at all inside it, except "call Stack_chk(250). Guess what - I got a continuous printout of "stack error3 in 250".
Why am i doing this - because about once week, there is a string (with my RTC dd/mm/yy:mm:ss ) which gets filled with something silly, which I suspect might be an over write of some sort. Impossible to find when its so intermittent. _________________ Neil |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Jan 14, 2013 10:23 am Post subject: |
|
|
i do not know which version you use but when i simulate it, i get no error.
Since 2075 there is an additional piece of code built into the dynamic memory code : when you try to use more frame memory than available ERR is set.
from the history :
- ERR is set to 1 when there is not enough frame space. you use frame space when using locals and
passing parameter byval. also a test like : if left(string,3)="value" will use temp space.
i can not imagine an app that uses more than 128 for $hwstack and $swstack. But framesize can grow rapid with nested subs and lot of locals. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Mon Jan 14, 2013 10:48 am Post subject: |
|
|
Thanks Mark. I have no locals, and little nesting, and none more that 2 layers deep. I am using 2073 ; are you saying that 2075 has built-in error memory use checking " Since 2075 there is an additional piece of code built into the dynamic memory code : when you try to use more frame memory than available ERR is set." or are you referring to STCHECK? _________________ Neil |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Jan 14, 2013 11:08 am Post subject: |
|
|
no, it always is checked. with or without stcheck.
it also prevents overlap from frame into the stack. what you can notice is that your strings is not assigned but that is simpler to figure out than to find a corrupted stack. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Mon Jan 14, 2013 11:16 am Post subject: |
|
|
thanks Mark. That's a big help. I'll change to 2075 tomorrow. Have you had a chance to look at the search issue I mentioned a few days ago? _________________ Neil |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Jan 14, 2013 11:31 am Post subject: |
|
|
you should update to 2076.
further i am not going to discuss other topics inside a topic. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Tue Jan 15, 2013 1:05 am Post subject: |
|
|
I have now upgraded to 2076 and am pleased to report that STcheck does not return the string of errors with exactly the same program, that I was getting with 2073.
Mark : what does Quote: | when you try to use more frame memory than available ERR is set. | mean? Where is this err is it STcheck or in 2076. How do I know if it is being set? Where is it?
I have now compiled my program with Code: |
$framesize = 1
$hwstack = 60
$swstack = 60
Disable Jtag |
and it runs fine. I am now totally confused, because surely frame = 1 must be too small. You said that strings will not be assigned - what does assigned mean? Do you mean allocated with their values within the program? if so, that appears to be working fine. I have a large no of strings and many numeric<--> string conversions to do with RTC, all of which appear to be working OK, so I am confused.
regards _________________ Neil |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Jan 15, 2013 4:07 pm Post subject: |
|
|
I understand the confusion.
stcheck is not related. when you use stcheck , a special library will be used.
when not using stcheck, the internal memory allocation routine _addsizetoframe has a check for the available frame size. but i see that this is only for passing parameters like :
declare somesub(byval l as long, byval s as string)
when you need more memory than available, err is set.
I wonder if it might be better to simply halt the program. then it is more clear where the problem is occurring.
What was missing : when using a local, or when a temp string is required, the old memory routine was used so you do not get an error. So that is why ERR was not set in your case.
I changed it so the new routines are used in all cases. And i also made them depending on $framecheck
Using $framecheck has little overhead but when passing lots of params and when calling a routine often, it might not be desired so when not specifying $framecheck, the old memory routine will be used which does not check the framesize.
I will make a proper example and run some more tests. I can send you a beta later so you can test it as well.
Instead of stopping, the stack address could be stored into eeprom too. then with some other code (or same code) you could determine the address where the problem occurred.
A check with stcheck would reveal problems too. _________________ Mark |
|
Back to top |
|
|
njepsen
Joined: 13 Aug 2007 Posts: 469
|
Posted: Sat Aug 22, 2020 7:44 am Post subject: |
|
|
7 years later:
My application has now grown to 8000 lines, and I am using 2.0.8.2.
I have spent 7 hours today unsuccessfully trying to find a bug .
I have a variable called "last_rain_tipL" which is a global long. It is set in only one place in the entire program.
BUT - when the following sub runs, from time to time that variable gets changed:
Code: |
'*************************************************************************************
Sub Pi_check_for_noise_event()
#if Isnoise = 1
Local Noiselevelnowsng As Single
local TLRNsng as single 'Trigger Level Right Now Single
local s as single 'scratchpad single
local mylevelstr as string * 50 'holds noise level + descriptor
'wind filter & Standdown filter
If Meters_secsng > 3.0 Then 'global wind speed m/sec
Print #1 , ">> No noise check, due to high WS = " ;
waitms 10
print #1, Meters_secsng ; " " ;
waitms 10
print #1, Date$ ; " " ; Time$
Exit Sub
Elseif Mystanddownint > 5 Then
Print #1 , ">> standdown=" ; Mystanddownint ; " " ; Date$ ; " " ; Time$
Exit Sub
End If
'******************************************************************
more code
#endif
end sub
|
If I don't call this sub, then the problem goes away, but I need to know why.
STcheck consistently returns zero, but I do not understand where STCHECK has to be called: i.e do i insert it in my sub " Pi_check_for_noise_event()" or in the sub that uses the variable that gets trashed?
QUESTIONS
What is the difference between STCHECK and $HWCHECK,$FRAMECHECK,$SOFTCHECK?? It seems from reading posts that many people have gotten different numbers from these functions, that don't stack up with STcheck??
I have not yet tried these functions - do they work correctly in 2082?
Does STCHECK set "error" or "err". In a post above, 'err' is talked about, but the help for STCHECK talks about 'error'??
I cannot understand the help for $frameprotect?? It seems to me that it is only valid when you call subs with parameters from an ISR ?? I don't do this. Should I use $frameprotect?
The help says
Quote: | If you have a function that calls an asm library, you must restore the I-flag" |
I don't understand this.
I have arbitrarily increased stack & frame by 100 each but no effect.
At this point I am guessing that I have a stack problem, but dont know which tools to use to find out.
Here are the current settings:
[/code] '*******************************************************************************
$regfile = "m1284pdef.dat"
$crystal = 9830400
$framesize = 900
$hwstack = 650 '
$swstack = 650
$frameprotect = 1
config submode = old
$include "config_mmcsd_hc.bas"
$include "config_AVR-DOS.BAS"
$PROG &HFF , &HC7 , &HD0 , &HFD _________________ Neil |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|