Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Memory Corruption Causing Bugs Elsewhere in My Code.

21 views
Skip to first unread message

John Ernst

unread,
Jul 29, 2002, 11:07:16 AM7/29/02
to
Hi everyone,

I am occasionally getting the following error code in VO2.5-b3:

Error Code 50 [ACCESS VIOLATION]
Subsystem VO-CODE
Error Subcode 5333
....

This error occurs when I'm comparing the second element of a two dimensional
array to a string constant. The first element of the array is a DBServer
and the second element is the name of the DBServer. Upon tracing through my
code in the debugger, I noticed that the data in the array is corrupted
before I even get to the compare statement where my code breaks. Thus, it
would seem that the cause of my error is not my compare statement.

The compare statement in question is in a function that is executed via the
VO Eval() function. Before executing this Eval() function, the data in my
array looks fine. After executing the Eval() function and my debugger is on
the first line of code in the function called by the Eval() function, the
data in my array appears corrupted. The first part of the
string data in the second element of the array looks like it was changed to
binary characters. Strangely, if I play around in the debugger by
evaluating expressions, like reading variable values and checking memory
stats, the data in my array sometimes gets fixed.

I tried replacing the Eval() function with the Evaluate() function, but this
did not seem to fixed the problem. And, I can reproduce this problem when I
am not running the debugger.

I'm sort of out of ideas. Has anyone had a similar problem. Your thoughts
would be appreciated.

John Ernst


Ed Ratcliffe

unread,
Jul 29, 2002, 11:26:19 AM7/29/02
to
John,

Would it be possible to show us a little bit of the code. You most likely
have a local variable that is out of scope in your eval expression.

Ed

Klaus Stinshoff

unread,
Jul 29, 2002, 11:37:29 AM7/29/02
to
Hello,

look at http://www.knowvo.com/ and search for 5333. Here you'll find some
articles about avoiding and tracking 5333 errors.

Klaus
"John Ernst" <jer...@healthlinesystems.com> schrieb im Newsbeitrag
news:ESc19.674228$om4.6...@news.easynews.com...

John Ernst

unread,
Jul 29, 2002, 1:03:40 PM7/29/02
to
Ed,

This is the Line of code that executes the eval function:

retVal := Trim(Eval(&('{|x| ' + cTemp + '}'), {oDbf2, oWin}))

This is what cTemp looks like:

CHECKLATETIME(X[1], X[2], 1, 1)

That I have a variable out of scope is an interesting idea. Though this
error happens only occasionally. If you can see the problem here, please let
me know. I appreciate your advice. Here is the entire function that calls
the eval that is breaking. I put a * in front of the lines that are being
executed. Thanks for you help. John

FUNCTION mergeTransform(cTemp AS STRING, oDbf2 AS DBServer, nWrite AS PTR,
oWin AS ZEROWINDOW, filtVar AS LOGIC, dateAsYear AS LOGIC, holdConv AS INT)
AS STRING


LOCAL retVal AS STRING
*IF noContinue
RETURN ""
*ENDIF
*cTemp := MSLTran(cTemp, CHR(13))
*cTemp := MSLTran(cTemp, CHR(10))

*IF dateAsYear
cTemp := Upper(cTemp)
cTemp := otherTran(cTemp, "DTOC(", "age(")
*ENDIF
*IF Instr("X[3]", cTemp) .or. Instr("X[4]", cTemp)
++forceC
retVal := Trim(Eval(&('{|x| ' + cTemp + '}'), {oDbf2, oWin, nWrite,
filtVar}))
*ELSE
* IF Instr("X[2]", cTemp)
* DO CASE
* CASE Upper(cTemp) = "T_V(X[1]:" .and. !("+" $ cTemp) .and. !("FAC_CD" $
cTemp)
retVal := merget_v(cTemp, oDbf2, oWin)

* CASE Upper(cTemp) = "SCH_TT(X[1]:CD"
retVal := mergeSch_tt(cTemp, oDbf2, oWin)
* OTHERWISE
* ++forceC
* retVal := Trim(Eval(&('{|x| ' + cTemp + '}'), {oDbf2, oWin})) // ******
Eval being executed.
* ENDCASE

ELSE
IF !(Instr("(", cTemp)) .and. oDbf2:FieldPos(Trim(SubStr(cTemp, At(":",
cTemp) + 1))) > 0
retVal := Trim(oDbf2:FIELDGET(oDbf2:FieldPos(Trim(SubStr(cTemp, At(":",
cTemp) + 1)))))
ELSE
++forceC
retVal := Trim(Eval(&('{|x| ' + cTemp + '}'), {oDbf2}))
ENDIF
ENDIF

ENDIF
*IF forceC > 3
* CollectForced()
* forceC := 0
*ENDIF


"Ed Ratcliffe" <Gryphon...@telus.net> wrote in message
news:v8d19.4033$Z5.1...@news1.telusplanet.net...

Ed Ratcliffe

unread,
Jul 29, 2002, 1:42:54 PM7/29/02
to
John,

>> * retVal := Trim(Eval(&('{|x| ' + cTemp + '}'), {oDbf2, oWin})) //

Try taking this apart. Compound expressions can be tricky in this case.
ie:
cbBlock := &("{|x| cTemp}")
retVal := Eval(cbBlock, {oDbf2, oWin})
retVal := Trim(retVal)

Ed

John Ernst

unread,
Jul 29, 2002, 2:01:15 PM7/29/02
to
Thank you Klaus. This is one of the best sources of information on VO
memory management I've come across.

John

"Klaus Stinshoff" <stin...@gmx.net> wrote in message
news:ai3nfq$8gl$00$1...@news.t-online.com...

John Ernst

unread,
Jul 29, 2002, 2:21:43 PM7/29/02
to
Ed,

I had gotten this suggestion earlier directly through an email, rather
than a posting, and I have already tried it. Unfortunately, it didn't seem
to help. Though it makes sense. Thanks for your suggestion anyway.

John Ernst


"Ed Ratcliffe" <Gryphon...@telus.net> wrote in message

news:y8f19.11344$Vj3.6...@news0.telusplanet.net...

John Ernst

unread,
Jul 29, 2002, 2:25:17 PM7/29/02
to
There is some excellant documentation on VO memory management out there. As
I read though it, I'm getting the idea that I'm going to have to make some
changes to my code to better help VO manage my program memory.

Thanks for you posting. John

"Klaus Stinshoff" <stin...@gmx.net> wrote in message
news:ai3nfq$8gl$00$1...@news.t-online.com...

malcolm.gray

unread,
Jul 29, 2002, 4:57:05 PM7/29/02
to

"John Ernst" <jer...@healthlinesystems.com> wrote in message
news:ESc19.674228$om4.6...@news.easynews.com...
> Hi everyone,

> The compare statement in question is in a function that is executed via
the
> VO Eval() function. Before executing this Eval() function, the data in my
> array looks fine. After executing the Eval() function and my debugger is
on
> the first line of code in the function called by the Eval() function, the
> data in my array appears corrupted. The first part of the
> string data in the second element of the array looks like it was changed
to
> binary characters. Strangely, if I play around in the debugger by
> evaluating expressions, like reading variable values and checking memory
> stats, the data in my array sometimes gets fixed.

I suggest that you look at dynwipe, this should make the app
fall over more thoroughly...

Good luck with it.

Malcolm (posting from home)


John Ernst

unread,
Jul 29, 2002, 5:23:31 PM7/29/02
to
Malcom,

Dynwipe doesn't exist in the VO help nor does my application compile
with dynwipe() in it. Is it possible that this is one of your own
functions?

John Ernst


"malcolm.gray" <malcol...@jobstream.co.uk> wrote in message
news:S%h19.3587$WO3.1...@newsfep1-win.server.ntli.net...

Geoff Schaller

unread,
Jul 29, 2002, 7:03:38 PM7/29/02
to
John,

I'm not at all happy with your code block execution but that aside, if you
hard code the strings as functions, does it work (ie for the moment, lose
the codeblock and just test the programming logic with actual code). If it
works then I suggest the Eval(&...) process is incorrect. Try constructing
proper _Codeblock expressions.

Secondly, try the code block with multiple params instead of an array. You
are adding dynamic overheads that will cause the GC to fire and thus "might"
cause you scoping issues on a random basis. viz:

{|x,y| expression...}, x, y

Geoff

"John Ernst" <jer...@healthlinesystems.com> wrote in message

news:Mze19.678432$om4.6...@news.easynews.com...

Malcolm Gray

unread,
Jul 30, 2002, 4:20:58 AM7/30/02
to
"John Ernst" <jer...@healthlinesystems.com> wrote in message news:<nni19.1185426$Bm3.1...@news.easynews.com>...

> Malcom,
>
> Dynwipe doesn't exist in the VO help nor does my application compile
> with dynwipe() in it. Is it possible that this is one of your own
> functions?

I'm sorry, I was hoping you would have found it on knowvo (I think it
is usually reffered to as dynwipe).
The is actually a registry key (I think I first saw it in SDT)

HKEY_CURRENT_USER\Software\ComputerAssociates\CA-Visual Objects
Applications\RunTime\WipeDynSpace=1

It causes the unused half of the GC memory to be zeroed.

Good luck with the corruption hunt. I suspect most of what I could
suggest
is already in knowvo.

Malcolm
(posted via google)

John Ernst

unread,
Jul 30, 2002, 11:39:32 AM7/30/02
to
Ok, I'll dig around out on knowvo for it. Sounds like it may be helpful.
Thanks again for you postings.

John Ernst

"Malcolm Gray" <malcolm...@jobstream.com> wrote in message
news:2a314851.02073...@posting.google.com...

Willie Moore

unread,
Jul 30, 2002, 11:47:06 AM7/30/02
to
John,

You wont find it in the docs. It is one of those things that the developers
slipped in. They first showed it at Technicon a few years ago. I can be very
useful in tracking down errors.

Regards,

Willie

ps Have you read Geoff's paper on 5333 errors? It is very good


"John Ernst" <jer...@healthlinesystems.com> wrote in message

news:nni19.1185426$Bm3.1...@news.easynews.com...

John Ernst

unread,
Jul 30, 2002, 1:14:18 PM7/30/02
to
Geoff,

I implemented your second suggestion, and that made the code break less
often. I can now execute my code around ten times before it breaks.
Whereas, it was consistently breaking the second time I executed the code.
I had to take the GC out of my code because that was making it break every
time I execute it.

Each time I run my code the Eval() functions in it get executed over a
100 times. Plus, there are several different functions being executed by
the Eval() function. And my code is not consistently breaking now and the
bebugger will not work when it does break. So, it would be difficult to
implement your first suggestion to hard code in the function calls, as I can
not tell which function the Eval() is breaking on. I am going to keep
thinking of ways to implement this suggestion.

My Eval() calls now look like this.

uTemp := &('{|oDbf2,oWin| ' + cTemp + '}')
retVal := Trim(Eval(uTemp, oDbf2, oWin))

Where cTemp = CHECKLATETIME(oDbf2, oWin, 1, 1)

Things are getting better. I guess I need to continue to go through my code
and find areas where things can be done differently. Your paper on
preventing the 5333 Error has been helpful. Thanks for you help. We all
appreciate it here.

John Ernst

"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message
news:eRj19.516172$o66.1...@news-server.bigpond.net.au...

John Ernst

unread,
Jul 30, 2002, 3:05:24 PM7/30/02
to
Willie,

I have read Geoff's paper on 5333 errors. And, I'm trying to see where
I can make adjustments to my code to prevent memory problems. As far as the
DynWipe() function goes, I can't compile with it in my code. So, I don't
think it is an undocumented function of VO. Do you know where it is?

John


"Willie Moore" <wil...@wmconsulting.com> wrote in message
news:ukdd8o9...@corp.supernews.com...

Karl Faller

unread,
Jul 30, 2002, 3:41:47 PM7/30/02
to
John,
in case you didn't see Malcolms message...

HKEY_CURRENT_USER\Software\ComputerAssociates\CA-Visual Objects
Applications\RunTime\WipeDynSpace=1

HTH
Karl

John Ernst

unread,
Jul 30, 2002, 4:23:43 PM7/30/02
to
Got it. Thanks.
"Karl Faller" <10072...@compuserve.com> wrote in message
news:3d46ebcf...@news.online.de...

Geoff Schaller

unread,
Jul 31, 2002, 8:06:09 AM7/31/02
to
John,

> I implemented your second suggestion, and that made the code break
less
> often. I can now execute my code around ten times before it breaks.

But I'm still not happy. I think you should be creating a _CodeBlock object
and executing that. Its a bit difficult to play without an app running in
your environment. Can't see where locals go out of scope etc. Remember that
you cannot send a local var to another function and expect it to wrk. The
time the GC fires in the executed function you are cactus. You can prove
this by turning off the GC during the execution of the codeblock.

> bebugger will not work when it does break. So, it would be difficult to
> implement your first suggestion to hard code in the function calls, as I
can
> not tell which function the Eval() is breaking on. I am going to keep
> thinking of ways to implement this suggestion.

No, not at all. Forget the debugger here - its one of the times where it is
not useful. Your code closk code is a string so of course you can display it
(say to a Debugview app) and so you can determine which one is failing.
Although I still think its a GC thing so its may not have anything to do
with the executed function itself.

> My Eval() calls now look like this.
>
> uTemp := &('{|oDbf2,oWin| ' + cTemp + '}')
> retVal := Trim(Eval(uTemp, oDbf2, oWin))
>
> Where cTemp = CHECKLATETIME(oDbf2, oWin, 1, 1)

As I said - I do not like this code in the least and would look for another
way to achieve the outcome. Perhaps someone else has some experience with
runntime expression evaluation?

Geoff


John Ernst

unread,
Jul 31, 2002, 6:50:49 PM7/31/02
to
Geoff,

Thanks again for you input. I have changed the code to use the _CODEBLOCK
object, but it's still failing after several successful calls. Here's what
it looks like:

LOCAL cb AS _CODEBLOCK

cb := &('{|oDbf2,oWin| ' + cTemp + '}')
retVal := cb:Eval(oDbf2, oWin)

Where cTemp = CHECKLATETIME(oDbf2, oWin, 1, 1)

I don't think I have a scoping problem, as it probably would always break if
I did. Please let me know if you have any more suggestions. Thanks again.

John Ernst

"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message

news:RoQ19.523354$o66.1...@news-server.bigpond.net.au...

Geoff Schaller

unread,
Aug 1, 2002, 7:49:56 AM8/1/02
to
Of course you have a scoping problem.

You should NOT send the variable, you should only send the contents of the
variable. When the code block is compiled you need to compile it with the
contents, never a variable name to be then accessed from another function
that never knew about the original variable. This is exactly a scoping
issue.

As I said, try turning off the GCbefore the code block execution and then
turn it back on again after. Does this also slow down the 5333's? As I keep
saying, I just expect 5333's from this kind of code.

Geoff

"John Ernst" <jer...@healthlinesystems.com> wrote in message

news:cRZ19.136076$Yk5.1...@news.easynews.com...

Don Carslaw

unread,
Aug 1, 2002, 9:56:20 AM8/1/02
to

Hi John,
I do something similar to you, sometimes compiling in a function.
I end up with cb = {|x,y| MyFunc(x,y)} (AS _CODEBLOCK)
I then do a cb:Eval(cMyLocalStringVar), but I _only_ pass in strings as
parameters.
I use this in a run-time logic engine for parsing text files, and have
include, exclude and substitute rules evaluated for each line.
So far I process up to a dozen rules per line in files over 50000 lines
with no problems, and it's surprisingly fast.
Here's a sample of a couple of rules that I read from a config file:
excluderule01=EMPTY(x)
excluderule02="****************"$x
I pass in the current line and if either of these evaluate to TRUE the
line is excluded. Simple stuff.

I have not had any problems that I can attribute to this type of
evaluation.
Maybe it's to do with the fact that you are passing complex objects?
HTH,
Don

John Ernst

unread,
Aug 1, 2002, 10:53:47 AM8/1/02
to
Don,

I think you are right about the fact that I am passing complex objects.
In fact, it is an array which is a property of the window object I am
passing that gets corrupted. But, I need the complex objects in the
functions I am calling. And, I can't think of a way to get rid of them.

Thanks for you feedback.
John


"Don Carslaw" <jcarslaw@~REMOVE4REPLY~amadeus.net> wrote in message
news:3d493e28$0$212$4d4e...@read.news.fr.uu.net...

Ed Ratcliffe

unread,
Aug 1, 2002, 11:23:02 AM8/1/02
to
John,

Are thse functions always called from a window?
If so is it always the same window or always the same root class?
If this is the case then can you not subclass the window/root and convert
all functions to methods of that class?
Then the values would be instances of that class and would be protected from
the CG. That is the way I have solved a similar problem. It usually possible
to break down a complex problem into many simple ones. One of the major
things I had to get my head around in moving from the Clipper environment
was, that there is no limit on number of funcion/method names. <G>

Ed


John Ernst

unread,
Aug 1, 2002, 11:50:25 AM8/1/02
to
Geoff,

I put a DynLock() before I execute my Eval() statement and a DynUnLock()
after I execute my Eval() statement, and my 5333 error seems to have gone
away. Ok, my GC is causing the error. This brings up a few questions:

1. If VO needs to call GC, but now it doesn't because I turned it off, why
am I not getting another type of memory error. Such as, I have run out of
dynamic memory?

2. If the GC is causing the 5333, how does scoping play into this?

3. It has been my experience in other programming languages that if a
variable is not scoped correctly, it will never work. But, in this
situation, it usually works. Why is this?

4. Do you think that turning off and on GC would slow up my application?
It seems to a bit.

> You should NOT send the variable, you should only send the contents of the
> variable. When the code block is compiled you need to compile it with the
> contents, never a variable name to be then accessed from another function
> that never knew about the original variable. This is exactly a scoping
> issue.

5. I thought I was doing this. How can I implement this is my code?

Thanks again for you help. We appreciate it very much.

John Ernst

"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message

news:Ef929.527571$o66.1...@news-server.bigpond.net.au...

John Ernst

unread,
Aug 1, 2002, 12:50:00 PM8/1/02
to
Ed,

I've been sitting here at my desk for the last 15 minutes thinking of
ways to implement this. These functions are called as a part of our
reporter, and there are dozens of them. And they are all called from a
function that is called from various other areas of the program. This idea
would probably help us. I'm just not sure how to fit it into our old code
without a big rewriting and testing effort. Thanks for the suggestion.

John

"Ed Ratcliffe" <Gryphon...@telus.net> wrote in message

news:qnc29.1957$%6.11...@news2.telusplanet.net...

Ed Ratcliffe

unread,
Aug 1, 2002, 1:08:36 PM8/1/02
to
John,

> without a big rewriting and testing effort. Thanks for the suggestion.

I rewrote, big effort.
I still don't like passing values to functions that pass them on to
codeblocks. Too many places for the CG to rear up and bite you.
Perhaps an interim solution would be a global object. Then your parameters
would be available without having to pass them to your function.

Ed

John Ernst

unread,
Aug 1, 2002, 3:02:40 PM8/1/02
to
Ed

That's something I could do. I've been chatting with Geoff Schaller
about turning off the GC before the Eval() and turning it back on after it.
It's seems to have eliminated the 5333 error I was having. Though I'm a bit
curious as to what kind of side effects I will have down the line, and my
code may be a bit slower. I have other Eval() functions in my code that are
causing problems too. So, I will keep your idea in mind, in case I can't
eventually get the Eval() working the way I think it should. Which would be
the easiest solution with the least impact.

Thanks again.

John


"Ed Ratcliffe" <Gryphon...@telus.net> wrote in message

news:oWd29.1969$%6.12...@news2.telusplanet.net...

Gary Stark

unread,
Aug 1, 2002, 5:36:37 PM8/1/02
to
Ed,

Yes, I'd agree. Either making the functionality a part of a window class, if
applicable, or else John should look OBJECTively <g> at the problem, and
consider writing a specific class to handle the data processing that he's doing
here. As you say, the functions etc that he's calling would become methods of
that class.


Ed Ratcliffe wrote:

--
g.
Gary Stark
gst...@RedbacksWeb.com
http://RedbacksWeb.com


Gary Stark

unread,
Aug 1, 2002, 5:51:47 PM8/1/02
to
John,

John Ernst wrote:

> Ed,
>
> I've been sitting here at my desk for the last 15 minutes thinking of
> ways to implement this. These functions are called as a part of our
> reporter, and there are dozens of them. And they are all called from a

Class MyClass

Method FunctionName1 Class MyClass

Method FunctionName2 Class MyClass

Method FunctionName3 Class MyClass

> function that is called from various other areas of the program. This idea
> would probably help us. I'm just not sure how to fit it into our old code
> without a big rewriting and testing effort.

You're moving, I suspect, code from DOS to Windows. Rewriting and testing is a
big part of that process, I'm afraid.

Function CalledFromEveryWhere()
local oClass as MyClass

oClass := MyClass{ }

// set up some report values
oClass:SomeParm := uWhatever

// call the equivalent of your old functions
oClass:FunctionName1()

// and so on.


> Thanks for the suggestion.
>
> John
>
> "Ed Ratcliffe" <Gryphon...@telus.net> wrote in message
> news:qnc29.1957$%6.11...@news2.telusplanet.net...
> > John,
> >
> > Are thse functions always called from a window?
> > If so is it always the same window or always the same root class?
> > If this is the case then can you not subclass the window/root and convert
> > all functions to methods of that class?
> > Then the values would be instances of that class and would be protected
> from
> > the CG. That is the way I have solved a similar problem. It usually
> possible
> > to break down a complex problem into many simple ones. One of the major
> > things I had to get my head around in moving from the Clipper environment
> > was, that there is no limit on number of funcion/method names. <G>
> >
> > Ed
> >
> >

--

John Ernst

unread,
Aug 1, 2002, 7:17:48 PM8/1/02
to
Gary,

I have a "Reporter" object that opens up many DBServers when running.
Rather than opening and closing and then reopening these DBServers over and
over again, they get stored in an array which is a property of the
"Reporter" object. I pass a reference to the "Reporter" object using
CB:Eval() to dozens of functions that look up the DBServers in my array and
use them. These functions gather data and stats from the database to return
to the reporter. Anyway, this is the array that gets corrupted when Eval()
is called.
These functions are also called normally from various other parts of my
code. So it would be a big job to implement something like you are
suggesting. But, my biggest fear is tweaking all of that code in a
relatively stable and mature piece of software and then shipping it to our
customers. We are running 2.5b-3 currently. And we've been using VO since
it was a beta product. So, really we have been doing this for a while.

Thanks for you suggestion.

John

"Gary Stark" <gst...@NOJUNKRedbacksWeb.com> wrote in message
news:3D49AD73...@NOJUNKRedbacksWeb.com...

Gary Stark

unread,
Aug 1, 2002, 8:00:28 PM8/1/02
to
John,
 

John Ernst wrote:

Gary,

      I have a "Reporter" object that opens up many DBServers when running.
Rather than opening and closing and then reopening these DBServers over and
over again, they get stored in an array which is a property of the
"Reporter" object.  I pass a reference to the "Reporter" object using


I have no argument with this approach, and it should be working fine. But - and I'm merely thinking aloud here - why wouldn't these server objects be properties of the class, with their own accessors? Something like

Class MyReportClass
    protect oClient as MyClientServer
    protect oInvoice as MyInvoiceServer
 

Access Clients Class MyReportClass

return self:oClient
 

might remove a small element of complexity from the class perhaps ?

 

CB:Eval() to dozens of functions that look up the DBServers in my array and
use them.  These functions gather data and stats from the database to return
to the reporter.  Anyway, this is the array that gets corrupted when Eval()


Again, I would be considering the basic design here. As you say, these functions gather data and stats from the database. To me, this suggests that the functions should probably be methods or accessors of your dataserver, rather than functions.

Then you could grab your data with syntax along the lines of ...

    cSomeVar := oMyReportClass:Clients:GetBalanceForMonth( 7, 2002 )

and

Method GetBalanceForMonth( nMonth, nYear ) Class MyClientServer
    local nRetVal as float

    nRetVal := 0

    self:GoTop()
    while !Self:Eof
        // Calculate stuff here
        self:Skip()
    end

return nRetVal

 
 

     These functions are also called normally from various other parts of my
code.  So it would be a big job to implement something like you are
suggesting.  But, my biggest fear is tweaking all of that code in a


Not quite as big as what, I suspect, you fear.

Add the functions to your dataserver, calling them methods, of course. Then just change your calls to reflect the new calling syntax.

 

relatively stable and mature piece of software and then shipping it to our
customers.  We are running 2.5b-3 currently.  And we've been using VO since
it was a beta product.  So, really we have been doing this for a while


I tend to query your "relatively stable" comment; if the app were stable you wouldn't be having this problem. <g>

Geoff Schaller

unread,
Aug 1, 2002, 8:12:35 PM8/1/02
to
John,

> I put a DynLock() before I execute my Eval() statement and a
DynUnLock()
> after I execute my Eval() statement, and my 5333 error seems to have gone
> away. Ok, my GC is causing the error. This brings up a few questions:

No, you are exactly 100% out of phase with reality here <g>. It is not the
GC breaking your code, it is the GC proving to you that you have broken code
<bg>. You are trying to do something which is simply not legal in a dynamic
memory world. As you have not really explained the need and reason behind
this functinal requirement it is a little difficult to offer alternate
solutions. maybe you'd like to start from the start rather than asking us to
help fix something which should not be fixed in that way?

> 1. If VO needs to call GC, but now it doesn't because I turned it off,
why
> am I not getting another type of memory error. Such as, I have run out of
> dynamic memory?

No. More misinterpretations <g>. The dynamic memory allocation system is
called every time dynamic allocations need to be made. If there is none left
to allocate, the GC is called to cleanup and move stuff around. The GC
doesn't get called everytime and it doesn't necessarily need to do anything
every time. You should read Uwe Holz's paper on the GC in a 1999 issue of
SDT. its the nearest thing we have to a bible on the subject.

> 2. If the GC is causing the 5333, how does scoping play into this?

No, the GC doesn't CAUSE a 5333, your program does because you are
referencing now illegal pointers in memory. All the GC did was its job. It
moved stuff about to accommodate your memory needs. Just because you use the
pointers illegally is not the fault of the GC. Your use of the code block in
this fashion guarantees this error. Don't blame your bad use of code blocks
on the GC <g>.

> 3. It has been my experience in other programming languages that if a
> variable is not scoped correctly, it will never work. But, in this
> situation, it usually works. Why is this?

?? Interesting. Does their definition of "scope" mean the same thing? How
can you compare C with VO, for example? Anyway, why can it 'sometimes' work?
Precisely because if the GC does not kick in, the pointers all exist at the
correct locations. So, turning off the GC allows you to break a few rules
and gain some flexibility. Same-same with turning off compiler warnings etc
and doing stuff with casting. With VO you have this power but with power
comes responsibility. You can break rules but you must know what you are
doing. Your use of code blocks here is incorrect in a dyunamic memory
environment. If you read the online help and the manual, its quite clear
about this.

> 4. Do you think that turning off and on GC would slow up my application?
> It seems to a bit.

Quite the reverse. By definition it must speed it up. But I don't think you
would notice those milliseconds <g>.

> 5. I thought I was doing this. How can I implement this is my code?
> Thanks again for you help. We appreciate it very much.

You will need to explain a little more about whatyou are doing. Of course,
though, there is the issue that if you can make this work flawlessly by
temporarily suspending the GC, why not?

Cheers,

Geoff


Geoff Schaller

unread,
Aug 1, 2002, 8:14:51 PM8/1/02
to
The global object is often the simplest way to carry around dynamic objects
and access them from remotely called functions. Even consider a system
object. Another way to kill the same bird.


"John Ernst" <jer...@healthlinesystems.com> wrote in message

news:kBf29.1437785$Bm3.2...@news.easynews.com...

John Ernst

unread,
Aug 2, 2002, 11:36:08 AM8/2/02
to
Gary,
 
     Of course you are right.  Our code in some ways is poorly written.  We owe this in part to the converting our app from DOS to VO, and not thinking about proper OO techniques.  We also owe some of this to the fact that the earlier versions of VO were buggy and we had to work around this is our code.  These two things make it hard for me to maintain our product.  Case in point, this 5333 error I am getting.  On September first, management is expecting me to release a new version of our product to our customers.  That's one more month.  I wish I could rewrite our reporter as you suggest, but my time constraints will not permit it.  I do have a solution for the 5333 error.  It's not optimal, but it will get our stuff out the door. 
 
Thanks,
John

John Ernst

unread,
Aug 2, 2002, 12:06:25 PM8/2/02
to
Geoff,

> You will need to explain a little more about whatyou are doing. Of course,
> though, there is the issue that if you can make this work flawlessly by
> temporarily suspending the GC, why not?

I'm going to go with this. Our code is a strange mix of OO programing,
funtions, and global variables. And we've been writing it since VO was in
beta, so there is a lot of it. This makes making sweeping changes to it
rather difficult and time consuming. The code in which the 5333 error
message is occuring is big and complex, and it would be an enormous chore to
reconstruct properly. And due to time constraints, I cannot do this. So,
you can understand that I am greatful this simpler fix.
Thanks for the info on dynamic memory. I'm going to need it to fix
other 5333 errors that are occuring in our program.

John

"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message

news:T7k29.528818$o66.1...@news-server.bigpond.net.au...

Ed Ratcliffe

unread,
Aug 2, 2002, 12:27:13 PM8/2/02
to
John,

>I do have a solution for the 5333 error. It's not optimal, but it will get
our stuff out the door.

Shudder...<g>
It may come back to bite you when run on a clients machine.

Ed

John Ernst

unread,
Aug 2, 2002, 1:36:52 PM8/2/02
to
Ed,

It may bite us. But, really it's fixing a bug our customers have already
found for us. So, I doubt this fix will make things worse. I could
reproduce the bug regularly on my machine. Now, I can't. This is a good
thing.

John

"Ed Ratcliffe" <Gryphon...@telus.net> wrote in message

news:Bpy29.12423$Z5.4...@news1.telusplanet.net...

Gary Stark

unread,
Aug 2, 2002, 9:29:18 PM8/2/02
to
John,

One more observation if I may.


> I'm going to go with this. Our code is a strange mix of OO programing,
> funtions, and global variables.

Kill the globals. Quickly.

Replace them with an iVar instance or accessor in App, MyApp, or some other
system wide object. The replacement code can be very easy to implement too:
change the calls in your code to the iVars to become object accessors or
methods, and then just replace your globals with the appropriate
method/accessor.

Your app will benefit greatly from this action, and the change is really quite a
trivial one to implement.

Geoff Schaller

unread,
Aug 3, 2002, 4:17:25 AM8/3/02
to
John,

Ok, well you have basically confirmed my suspicion that it is the code at
"fault" - but I hasten to say that I am not criticising you - I appreciate
these things evolve over time and often we'd change things with new
knowledge, as long as someone was going to pay for it <g>.

So, quite simply, use Dynlock(), execute your code block - DynUnlock().

As long as you don't run out of dynamic memory (and it sounds unlikely), why
not? If you can't/don't want to change the code then this is your way out.

Another point, although I note Gary's point about globals, you can use
Privates quite safely in code blocks. This may be another way out for you.
Read the manual. it explains why.

Geoff


"John Ernst" <jer...@healthlinesystems.com> wrote in message

news:56y29.1520670$Bm3.2...@news.easynews.com...

John Ernst

unread,
Aug 5, 2002, 11:03:25 AM8/5/02
to
Geoff,

Modifying this old code does take a balanced approach. Especially in
consideration of our resources and customer demands. Sometimes it's hard
for me not to do something the best way in order to get a release out of the
door. Because I know there's a good chance I'll be revisiting the issue
later, if I take a patch it up approach. I'm hoping this fix will hold the
water. Thanks again.

John

"Geoff Schaller" <ge...@softwareobjectives.com.au> wrote in message

news:pkM29.1376$sp1....@news-server.bigpond.net.au...

John Ernst

unread,
Aug 5, 2002, 11:06:33 AM8/5/02
to
Gary,

I would love to kill the globals. Hopefully, someday time will permit me
to do this. Thanks again.

John

"Gary Stark" <gst...@NOJUNKRedbacksWeb.com> wrote in message

news:3D4B31EE...@NOJUNKRedbacksWeb.com...

0 new messages