06230551.txt 23-Jun-00
Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
HELP!!!
From the outset we've been plaugued by 4660 errors in our
large VO2 application, and whilst some of our 50+ sites
have been tollerating it, others are understandably
getting pretty fed up.
Now we've ported the app to VO2.5 and sure enough, we found
loads of 5333's caused by nasties from a byegone age, and
have spent the last three weeks putting right these past
sins.
However, the app is still remarkably flaky, and is not even
ready for first testing. Unless we set DyneSize(40), we
can't keep it up above a couple of minutes --- not a
pretty sight!
We've studied the stitaution in detail, read Rod da Silva's
article till we can recite it backwards (almost), and have
tried just about everything we can think of --- and still
no joy.
We've opened and altered EVERY binary entity, re-indexed the
repository, exported and re-imported modules, revisted all
the dbServers and made sure we close everything properly,
and set objects to NULL_OBJECT. Still, when the Garbage
Collector kicks
in, (we have a Garbace Collect button on hand and perform
the ceremony at will!) its inevitable that the app will
die almost instantly. All we can imagine is memory
corruption on a massive scale! Even WipeDynSpace has not
helped us.
Does anyone have any ideas, or can recommend anything short
of valium or an extremely sharp knife?
Growing greyer by the day!
John M Roe
RE: Drowning in a sea of 5333 Errors!
Posted by: williem
John,
My understanding about the DynSize function is that it
allocates pages of dynamic memory that are availably for
VO. The Garbage collector will try to free up the memory.
The larger the program, the more dynamic memory you might
require. I initially went with dynSize(40) based on stuff
I read from Larry Atkins (ReportPro). You might have to go
to a higher dynsize to give yourself enough dymamic memory
to let the garbage collector do it's thing.
On my com programms (using VOCOM or 25's native), I have to
close out each method with the
if !incollect()
collectforced()
endif
Otherwise, after the program has ben running for a while, it
will run out of dynamic memory and abort. Not good when it
is running under IIS.
Here is the skeleton that I use:
Method somemethod() class myWebService
LOCAL nRet AS LONGINT
LOCAL oError AS USUAL
LOCAL bErrBlock AS CODEBLOCK
LOCAL oRS AS ADOServer
LOCAL cSQL AS STRING
bErrBlock := ErrorBlock({|oErr| _Break(oErr)})
#IFDEF __DEBUG
goLogFile:DebugMsg("getting next Distributor Number")
AltD()
#ENDIF
BEGIN SEQUENCE
nRet := 0
// make sure that the database is really open
IF SELF:openDB()
cSQL := "select LastDistNun from LastDistNum "
oRS := ADOServer{cSQL,oConn,NIL,NIL,NIL}
IF oRS:BOF .and. oRS:EOF
// no records
BREAK 1
ENDIF
nRet := oRS:FIELDGET(#LASTDISTNUM)
oRS:FIELDPUT(#LASTDISTNUM, nRet)
oRS:update()
oRS:Close()
ELSE
BREAK 0
ENDIF
RECOVER USING oError
#IFDEF __DEBUG
goLogFile:DebugMsg("Error retrieving distNum")
#ENDIF
IF IsNumeric(oError)
DO CASE
CASE oError = 0
#IFDEF __DEBUG
goLogFile:DebugMsg("Error opening database")
#ENDIF
CASE oError = 1
#IFDEF __DEBUG
goLogFile:DebugMsg("Error no records found")
#ENDIF
ENDCASE
nRet :=0
ELSE
// pass on the error block
nRet = -99 // VO runtime Error
// Eval(bErrBlock, oError)
ENDIF
END SEQUENCE
ErrorBlock(bErrBlock)
oRS := NULL_OBJECT
IF !inCollect()
CollectForced()
ENDIF
RETURN nRet
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Hi Willie
Many thanks for the tips - You've clearly had it bad too!
My collegue and I are about to start hunting around modules
for any other hidden nasties - redundant defines etc which
may be hidden, but we'll also take a good look at the
skeleton you kindly sent.
From the research we've done, it looks as though pointers
are getting corrupted by the garbage collector - in fact
we took some ideas from Rod's SDT article, and actually
saw pointers being changed as the GC did its bit. What we
can't work out, is how the hell to stop it.
We'll also up the Dynamic Memory, but I'm not sure at what
point that could cause problems of its own - if the user
has insufficient RAM, will the whole app fail to run
anyway? At the moment its split into a 5.2Meg EXE and a
3.5 meg DLL, so as you can see, there's one hell of a lot
of work to do!
Anyway, thanx again and I'll keep you informed.
Kindest
John
RE: Drowning in a sea of 5333 Errors!
Posted by: Stefan Dietl
Once (20b) I used a inifile class with api-calls using
string2psz(cstring). After removing those api-calls by
using stringalloc(cstring) I got a much more stable app
with less 4660.
Another stupid mistake I made was to create an order to a
field not existing in the table. VO will not give an
error, you can open a bad indexed file many times without
crashing - but the GC will not forgive You...
Perhaps not really news...
good luck
Stefan
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Hi Stefan
We're exploring ALL avenues, so any help is appreciated.
Thanx
John
RE: Drowning in a sea of 5333 Errors!
Posted by: mlincoln
John,
As you may have realized, the problems you are experiencing
result from dynamic memory being moved by the garbage
collector thus invalidating a pointer to said memory. You
should take extra care to review any areas in your code
that might cause this.
The classic is casting or converting a string to a psz.
Allocating a true static string using StringAlloc() solves
this problem. I have some experience with finding these
type of problems, so if you would like some assistance,
let me know.
Mark
RE: Drowning in a sea of 5333 Errors!
Posted by: Marek W. Zawolek
Hi,
I in the middle of dealing with a similar problem. Let me
tell you about some of experiences.
I have a large VO 2.0 application thet was working almost
fine, only occasionally having some unexpected problems
that I tracked down to GC messing my arrays to the point
that for instance ALEN() was reporting thousands of
elements instead of just a few. With VO 2.5 things went so
wrong that the application was dying almost every time.
Playing with VO 2.5 by "try anything" I noticed the
following:
1. my application was first reading all report definitions
(my own simple report-writer), macro compiling them end
executing
2. all the definitions were being stored in collections (1-
dimensional arrays of objects, each holding all the
definitions for a single entity)
3. VO 2.0 stopped having ANY problems and VO 2.5 improved
after (SURPRISE!!!) instead of loading the definitions to
each object through INIT ther was calling SUPER:INIT (the
default generic for each object), I leaved INIT as default
only and I was loading data through another method called
after the object was instantated. It sounds strange, as it
should have no effect, but somehow GC was OK in 2.0 and
less corruptive in 2.5.
4. With 2.5 I noticed that if I run my report with small
amount of data so GC does not kick-off during the
reporting and then I run a second report with the large
amount of data, everything goes fine, but starting with
large amount of data almost always ends with 5333.
CollectForced before and after some big operations did not
help.
So thanks to 2.5 my 2.0 application became absolutly stable,
but I still cannot have my 2.5 version running.
I KEEP WORKING ON IT!!!
Good luck, I am happy to be in a good company.
Marek
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Thanx Marek
Glad to see we're not alone - I just wonder how many folk
are struggling with this one, or just keeping quiet and
hoping that it will go away!
There is a big problem with the GC shifting things around
and we have created a situation where we've seen pointers
change after the GC's kicked in, exactly as Rod da Silva
pointed out in his article for SDT.
The big issue is, how exactly do you stop it!
Also, if we use DyneSize to allocate more memory, and stave
off the problem, what are the guidelines. Should teh
default size work, or should we experiment and find a
suitable value.
It would be great if someone could give some definative
answers, as this is costing us a lot of money now. We are
trying to ship a big multi-user app to about 50 clients,
and just daren't send it out. We can't even do our in
house testing as the app is too unstable. We can mask it
by ramping up DynSize, but gather that this is not really
the answer.
Lets just hope that one day someone might come clean on
this.
Regards
John
RE: Drowning in a sea of 5333 Errors!
Posted by: Marek W. Zawolek
Hallo again,
I really feel better, because for quite a while I thought
that it is just my sloppy way of programming responsible
for all this mess.
I have to admit that now when I increased DYNSIZE to 40 my
VO 2.5 application behaves much better and observing 2.0 I
noticed that it was much easier with my app to get
DYNSIZEINFO size over 200 whereas 2.5 always keeps it at
minimum e.g. 40. My guess is that 2.5 gets into errors
when it tries to increase DYNSIZE by itself.
As things improved with my app after moving filling objects
from INIT into some other METHOD called after
initialization, perhaps you can try to do it with your
app. Also remember to NULL_ARRAY all your instance arrays
and NULL_OBJECT all your instance objects in the CLOSE
method of your objects.
I admit it maybe quite time consuming (it took me days as I
had plenty of this kind of objects), but otherwise we have
to wait for 2.5B - it looks like VO gets better with B
releases.
Good luck
Marek
RE: Drowning in a sea of 5333 Errors!
Posted by: Marek W. Zawolek
Hi John,
"Playing" with VO 2.5 I just noticed that setting your
memory with DYNSIZE only once may not be enough. It looks
like VO 2.5 tries to be smart and occasionally it reduces
dynamic memory later even to 20 instead of 40 set by
DYNSIZE. Therefore in some critical places I have added
the following code:
IF DynInfoSize() < 40
DynSize(40)
ENDIF
The appication behaves much better.
Regards
Marek
RE: Drowning in a sea of 5333 Errors!
Posted by: sburak
Hi John,
in addition to what others say, put this code in your
Close() Methods
WHILE TRUE
ApplicationExec( EXECWHILEEVENT )
IF ! InCollect()
CollectForced()
EXIT
ENDIF
END
This is in my oppinion better then
IF ! InCollect()
CollectForced()
ENDIF
However, my experience is that most of the 5333/4660 errors
arrive from bad coding, ie referencing to objects that are
out od scope etc.
Hope this helps little bit,
Senad Burak
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Hi Senad
This sounds a useful tip and its going in right away!
Thanx
John
RE: Drowning in a sea of 5333 Errors!
Posted by: hourant
Hi Senad,
I'm not sure that Collecforced() solves the 5333 error.
AFAIK, this just runs the GC collector to work more often
than usual. If the coding is properly done you shouldn't
force the GC to work by yourself.
But this should shows the 5333 error closer to the point
where the error really is.
I totaly agree with you about the bad coding and the object
that are out of scope.
We have reduced drasticaly our own 5333 errors with the
registeraxit and axit method.
Now, when we create an new object, the first things we do is
to place a registeraxit(self) in its init method and
create an axit() method that calls a destroy method.
Even if there is nothing to clean, the method is there and I
can be sure that it will be called by the GC.
Another trick is to display the number on axitregistered
objects on the status bar. This number should always be
very low when trese is no opened "object". When you leave
a window, this value should come down to the value it was
before opening the window. You should check Geoff Canvas
sample (I think it's on knowvo.com).
With 2.5x, we have wiped off all the collectforced with used
to use in 2.0.
Just my 2 cents.
HTH
Eric
RE: Drowning in a sea of 5333 Errors!
Posted by: Paul Bartlett
Senad,
In my experience putting an ApplicationExec() in Window
close routines can cause other side effects. Users who are
fast with their mouse can start clicking around the
application, or even close the app before your child
window close method has finished.
Best wishes,
Paul Bartlett
RE: Drowning in a sea of 5333 Errors!
Posted by: hourant
Hi John,
Unfortunatly, I cannot give you THE answer to solve the 5333
errors. Every time I got this error, I have found the
solution in my own code.
One of our customers reported a 5333 error a few months ago.
Updating his video drivers solved the problem.
We have quite large applications running and no one has
reported this error for a long time.
I also think that NT is much more stable than 9x and we
advice all our users to use this OS
Eric
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Hi Eric
Thanks for the info.
Regards
John
RE: Drowning in a sea of 5333 Errors!
Posted by: Arne Ortlinghaus
Hello John,
perhaps you could insert an additional Testfunction which is
enabled/disabled by a global switch which makes the
following:
if !_DynCheck()
MsgError ("Error in Memory " AsString (DynCheckError()))
endif
if !InCollect()
CollectForced()
endif
And then insert the function in as many places as possible.
(It makes program much slower) Perhaps you see an error a
bit earlier. The problem is that if the error happens in
the garbage collector it is too late to see the reason.
The other thing is that in my opinion there can be still
problems in arrays that contain objects which are
referenced in other arrays. Although in our sight every
thing seem to work quite well at the beginning I had
problems when buffering too much data in "global arrays"
with too complex referencing the objects in the array.
Maybe the garbage collector does not always know what to
do.
Another thing could be to look at objects that have a
destroy-Method. Perhaps you can insert a protect-variable
that disables the second call of the inner part of the
destroy method.
And perhaps after using a modal dialog or other objects with
a Destroy-Method that you destroy it yourself and than set
the variable to Null_Object. And afterwards call the
testfunction above.
Arne Ortlinghaus
RE: Drowning in a sea of 5333 Errors!
Posted by: JOHNROE
Hi Arne
Thanx for the info - all ideas are welcome. Also the
DynCheck sounds useful to try.
Kind regards
John
RE: Drowning in a sea of 5333 Errors!
Posted by: TomWalden
John,
FYI, I've finally gotten rid of all but one scenario of my
"Access Violation" (error codes 50 _{038}_ 5333) problems.
In addition to using 2.5a1 with it's new fixes, I made the
following changes in my code that corrected most of the
problems. I realize that others have mentioned these and
other suggestions, but these are what finally worked for
me, so here is my 2 cents worth:
1. I was using global arrays (about 15) for use in all my
various comboboxes. Instead I made a global oShell object
and made all those arrays as instance variables in that
shell class.
2. I strong-typed all of my methods in ALL of my classes. I
also used the ~"OpenEarly /-" declaration in each of my
"class - declare method" source code.
3. I made as many LOCAL variable objects early bound as
possible. Whenever I was through with an object used in a
method (or function), I would set that object :=
NULL_OBJECT (especially for dbServer objects) to help the
garbage collector. When I was through with arrays I also
set them to NULL_ARRAY ( a biggee ).
4. After setting my NULL assignments (like when closing a
window), before and after calling a ReportPro object, and
after calling a ListView:DeleteAll() methd, I inserted the
following code:
IF !InCollect()
CollectForced()
ENDIF
I also did a CollectForced() firtst thing in the :Start()
method of every app.
5. In a third party browser (bBrowser), it did not like
macro expansion of field names for setting column color
assignments. I replace the area with the macro logic with
a large case statement and it works fine now.
Go figure.
The bottom line is that most of the changes were converting
as much as possible into OOP logic and the other was
helping out the garbage collector. Although I still think
that VO has some memory handling problems, at least almost
everything is working right now due to some coding
changes.
HTH,
Tom
RE: Drowning in a sea of 5333 Errors!
Posted by: mrg17
Do you ever write code like
FOo(x:=y(),z) ?
If you look on the news groups you will see I posted last
week (I have been away since) about a problem that if y()
triggers the GC then Z (not x) is invalidated.
This seems to have help A LOT with out 5333 problem.
Note that we detected this using many things but IsDynPtr
was a great help.
               (
geocities.com/n_s_wong/vo)                   (
geocities.com/n_s_wong)