Solved

Stack Overflow and $MAXSTACKSIZE

Posted on 2003-12-08
21
900 Views
Last Modified: 2010-04-05
Hi

I am a very experienced database programmer in VB with Access and SQLServer.

I have built a database program in Delphi7. I have a data object which supplies the data to a form.  On the form there are basically two grids with two different record sets.

I sort the data on the grids and add and remove data - nothing out of the ordinary.When I close the form I do quite a lot of processing in the query unload to update another table.

Now heres the thing - when I just open the form and close it there are no problems - the data is processed fine - so far so good - I can open and close the form 100 times.

It appears that after sorting the records on the form several of times (it can be ten times or 50 times) - when I close the form (and do the processing) I get a stack overflow error. There is no error in the Code - the data and Code in the query close event are unchanged.

I am absolutley not making recursive calls (looping etc) and it is impossible to pinpoint the problem - it appears random.

How can I find the problem/view/monitor the stack - what would be the effect of increasing the $MAXSTACKSIZE ?

Points for good answers onlty please - I have searched the Web High and Low - so
0
Comment
Question by:Voodooman
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 7
  • 3
  • +1
21 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9902666
do you have assigned any event-methods?
if yes which?
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9902708
Hi kretzschmar

This is the code that seems to build the stack - but I cant see how it can - the stack error occurrs later when I run Code under the CloseQuery.  Running the Close query without using the code below seems to be OK.

T

procedure TF_AreasMain.CBO_SortJobsClick(Sender: TObject);
var sql:TStrings;
  filterStr:string;

  Begin



    //Filter the recordset - use sql - cus the filter is rubbish
    //**********************************************************

    Try

      wait(True);
      sql:=TStringList.Create;


      case CBO_SortJobs.ItemIndex of

        1: filterStr:=' and Status Like ' + quotedstr('Completed%');
        2: filterStr:=' and Status Not Like ' + quotedstr('Completed%');
        3: filterStr:=' and OverEstimate > 0 and Status Like ' + quotedstr('Completed%');
        4: filterStr:=' and UnderEstimate <> 0 and Status Like ' + quotedstr('Completed%');
        5: filterStr:=' and Status=' + quotedstr('In Progress');
        6: filterStr:=' and Status=' + quotedstr('Cancelled');
        7: filterStr:=' and Planned<>True';
        8: filterStr:=' and Planned=True';


      end;

        sql.Add('Select * from Labour where Area=' + quotedstr(data.Area));
        sql.Add(' and ProjectID=' + IntToStr(data.ProjectID));
        sql.Add(filterStr);
        sql.Add(' order by Trade,Workman,Description');
        dataobj.EQ_Labour.SQL:=sql;
        dataobj.EQ_Labour.Active:=False;
        dataobj.EQ_Labour.Active:=True;

        Grid_Labour.SetFocus;
        sql.Free;
        wait(False);

    Except

    On E: Exception do

     Imessage('Error filtering Jobs - ' + E.Message);

    end;

  end;
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9902737
well, i see also no problem yet.

what does wait()?
any event-methods on dataobj.EQ_Labour?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Author Comment

by:Voodooman
ID: 9902790
Hi kretzschmar

Thank you.

Wait() just shows/hides the mouse pointer hourglass - it doesnt actually stop or do anything.

There are no events on EQ_Labour.  The code I have shown doesnt in itself cause the 'Out of Stack'.

It just seems that doing this x times contributes to it.  I have code under the close query that appears to cause it.  The Code itself does not actually cause the 'Stack Overflow' as the Code never even runs!

The Code runs fine (with no changes in the data other than the filtering 90% of the time.
Voodooman
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 9902915
well, digging in the dark as you ;-)

how looks your close-qeury-code?
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 9903129
Doesn't running in the debugger help you? When the stack overflow occurs, look at the stack..! Are you _sure_ you're not accidentally calling recursivley. Interconnected events are an obvious possibility, as has been mentioned.
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9904372
Hi

I am certainly digging in the dark!  The stack overlflow is completley unpredicatable.  I have tried very hard to reproduce it on demand.  I have worked on software testing in the past and have documented everything.

As far as the close query is concerned putting a breakpoint on the first line doesnt help - it doesnt even get there!

I can test for 10-15 minutes with no problems whatsoever.  I can close the program down and when I re-open it after working for only a minute - BANG! overflow.  Does anyone know of anytool that can show how much of the stack has been consumed/free?

I have increased the stack to 2mb and I dont seem to be having any problems at the moment - here is the close query - it does not call recursively.

//*******************************************//
//  Procedure: TF_AreasMain.FormCloseQuery
//*******************************************//
procedure TF_AreasMain.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);

  var sql:TStrings;
        countCosts:Integer;
        countLabour:Integer;
        totalCount:Integer;
        recCountCosts:Integer;
        recCountLabour:Integer;

        //Fields
        //******
        Completed:Boolean;
        Budget:Single;
        CurrentEstimate:Single;
        Spent:Single;
        ToSpend:Single;
        OverBudget:Single;
        UnderBudget:Single;
        EstimatedHours:Single;
        CurrentEstimatedHours:Single;
        ToDoHours:Single;
        ActualHours:Single;
        OverEstimateHrs:Single;
        UnderEstimateHrs:Single;
        CompletedJobs:Boolean;
        CompletedCosts:Boolean;
        BalanceCosts:Single;
        BalanceHours:Single;





  begin

  Try

  if askquestion('Finish Updating ' +data.Area +'?')=False  then
    begin
      canClose:=False;
      Exit;
    end;

  Wait(True);



  //Need to update the Areas table with the totals
  //**********************************************
  //A bit of SQL should do it! - get the totals
  //*******************************************

  //Totals - not the Estimates - these are logically not just the totals
  //********************************************************************
  sql:= TStringList.Create;
  sql.add('Select sum(ActualCost) as ');
  sql.Add('ActualCost,sum(OverEstimate) as OverEstimate,sum(UnderEstimate) as ');
  sql.Add('UnderEstimate from Costs  ');
  sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));

  dataobj.EQ_General.Active:=False;
  dataobj.EQ_General.sql:=sql;
  dataobj.EQ_General.Active:=True;


  if dataobj.EQ_General.FieldValues['ActualCost']=null then
     spent:=0
     else
     Spent:= dataobj.EQ_General.FieldValues['ActualCost'];

  if dataobj.EQ_General.FieldValues['OverEstimate']=null then
     overBudget:=0
     else
     OverBudget:=dataobj.EQ_General.FieldValues['OverEstimate'];

  if dataobj.EQ_General.FieldValues['UnderEstimate']=null then
     UnderBudget:=0
     else
     UnderBudget:=dataobj.EQ_General.FieldValues['UnderEstimate'];


  //Labour
  //******
  sql.Clear;
  sql.add('Select sum(ActualHours) as ');
  sql.Add('ActualHours,sum(OverEstimate) as OverEstimate,sum(UnderEstimate) as ');
  sql.Add('UnderEstimate from Labour  ');
  sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));

  dataobj.EQ_General.Active:=False;
  dataobj.EQ_General.sql:=sql;
  dataobj.EQ_General.Active:=True;


  if dataobj.EQ_General.FieldValues['ActualHours']=null then
     ActualHours:=0
     else
     ActualHours:= dataobj.EQ_General.FieldValues['ActualHours'];

  if dataobj.EQ_General.FieldValues['OverEstimate']=null then
     OverEstimateHrs:=0
     else
     OverEstimateHrs:=dataobj.EQ_General.FieldValues['OverEstimate'];

  if dataobj.EQ_General.FieldValues['UnderEstimate']=null then
     UnderEstimateHrs:=0
     else
     UnderEstimateHrs:=dataobj.EQ_General.FieldValues['UnderEstimate'];


  //Flag the Completed flag
  //***********************
  //get the number of incomplete Costs
  //**********************************
  sql.Clear;
  sql.add('Select count(*) as Total from Costs where Completed=False and Status<>' +quotedstr('Cancelled'));
  sql.Add(' and ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));

  dataobj.EQ_General.Active:=False;
  dataobj.EQ_General.sql:=sql;
  dataobj.EQ_General.Active:=True;

  countCosts:=dataobj.EQ_General.FieldValues['Total'];

  //get the number of incomplete Labour Items
  //*****************************************
  sql.Clear;
  sql.add('Select count(*) as Total from Labour where Completed=False and Status<>'+quotedstr('Cancelled'));
  sql.Add(' and ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));

  dataobj.EQ_General.Active:=False;
  dataobj.EQ_General.sql:=sql;
  dataobj.EQ_General.Active:=True;

  countLabour:=dataobj.EQ_General.FieldValues['Total'];



  if CountLabour=0 then

      CompletedJobs:=True
      else
      CompletedJobs:=False;

  if CountCosts=0 then
        CompletedCosts:=True
        else
        CompletedCosts:=False;


  //Add the totals together >0 its not complete
  //*******************************************
  totalCount:=countLabour+countCosts;


  if totalCount=0 then
      Completed:=True
      else
      Completed:=False;



  recCountCosts:=dataobj.EQ_Costs.RecordCount;
  recCountLabour:=dataobj.EQ_Labour.RecordCount;



  //No Recs at all - mark it incomplete
  //**********************************
  totalCount:=recCountCosts+recCountLabour;


  if totalCount=0 then
    Begin
    Completed:=False;
    CompletedCosts:=False;
    CompletedJobs:=False;
    end;


    //Get the To Spend Amount
    //These do not include cancelled or completed Items
    //**************************************************
    sql.Clear;
    sql.add('Select sum([EstimatedCost]) as ToSpend ');
    sql.Add('from Costs  ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Status<>' + quotedstr('Cancelled') + ' and Status Not Like ' + quotedstr('Completed%'));
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;

   if dataobj.EQ_General.FieldValues['ToSpend']=null then
      ToSpend:=0
      else
      ToSpend:=dataobj.EQ_General.FieldValues['ToSpend'];




    //Get the ToDo Hours
    //These do not include cancelled or completed Items
    //**************************************************
    sql.Clear;
    sql.add('Select sum([EstimatedHours]) as ToDo ');
    sql.Add('from Labour  ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Status<>' + quotedstr('Cancelled') + ' and Status Not Like ' + quotedstr('Completed%'));
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;



    if dataobj.EQ_General.FieldValues['ToDo']=null then
       ToDoHours:=0
       else
       ToDoHours:=dataobj.EQ_General.FieldValues['ToDo'];


    //Get the Planned Cost
    //********************
    sql.Clear;
    sql.add('Select sum(EstimatedCost) as EstimatedCost from costs ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Planned=True');
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;

    if dataobj.EQ_General.FieldValues['EstimatedCost']=null then
       Budget:=0
       else
       Budget:=dataobj.EQ_General.FieldValues['EstimatedCost'];




    //Get the Planned Estimate of the Hours
    //These do not include cancelled
    //**************************************
    sql.Clear;
    sql.add('Select sum([EstimatedHours]) as EstimatedHours ');
    sql.Add('from Labour  ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Planned=True');
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;


    if dataobj.EQ_General.FieldValues['EstimatedHours']=null then
       EstimatedHours:=0
       else
       EstimatedHours:=dataobj.EQ_General.FieldValues['EstimatedHours'];


    //************************
    //Get the Current Estimate
    //************************
    sql.Clear;
    sql.add('Select sum(EstimatedCost) as CurrentEstimate from costs ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Status<>' + QuotedStr('Cancelled'));
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;

    if dataobj.EQ_General.FieldValues['CurrentEstimate']=null then
       CurrentEstimate:=0
       else
       CurrentEstimate:=dataobj.EQ_General.FieldValues['CurrentEstimate'];

    //Get the Current Estimate of the Hours
    //These do not include cancelled
    //**************************************
    sql.Clear;
    sql.add('Select sum([EstimatedHours]) as CurrentEstimatedHours ');
    sql.Add('from Labour  ');
    sql.Add('where ProjectID='+ intToStr(data.ProjectID) + ' and Area=' + quotedstr(data.area));
    sql.Add(' and Status<>' + QuotedStr('Cancelled'));
    dataobj.EQ_General.Active:=False;
    dataobj.EQ_General.sql:=sql;
    dataobj.EQ_General.Active:=True;

    if dataobj.EQ_General.FieldValues['CurrentEstimatedHours']=null then
       CurrentEstimatedHours:=0
       else
       CurrentEstimatedHours:=dataobj.EQ_General.FieldValues['CurrentEstimatedHours'];



    //Balance
    //*******

    if dataobj.EQ_Costs.RecordCount>0 then
       begin
       BalanceCosts:=OverBudget + UnderBudget
       end;


    if dataobj.EQ_Labour.RecordCount>0 then
         begin
         BalanceHours:=OverEstimateHrs + UnderEstimateHrs;
         end;



    sql.Free;

    //Now post the values
    //*******************
    dataObj.EQ_Areas.Edit;

    dataObj.EQ_Areas.FieldValues['Completed']:=Completed;
    dataObj.EQ_Areas.FieldValues['Budget']:=Budget;
    dataObj.EQ_Areas.FieldValues['CurrentEstimate']:=CurrentEstimate;
    dataObj.EQ_Areas.FieldValues['Spent']:=Spent;
    dataObj.EQ_Areas.FieldValues['To Spend']:=ToSpend;
    dataObj.EQ_Areas.FieldValues['Over Budget']:=OverBudget;
    dataObj.EQ_Areas.FieldValues['Under Budget']:=UnderBudget;
    dataObj.EQ_Areas.FieldValues['EstimatedHours']:=EstimatedHours;
    dataObj.EQ_Areas.FieldValues['CurrentEstimatedHours']:=CurrentEstimatedHours;
    dataObj.EQ_Areas.FieldValues['ToDo Hours']:=ToDoHours;
    dataObj.EQ_Areas.FieldValues['ActualHours']:=ActualHours;
    dataObj.EQ_Areas.FieldValues['OverEstimateHrs']:=OverEstimateHrs;
    dataObj.EQ_Areas.FieldValues['BalanceCosts']:=BalanceCosts;
    dataObj.EQ_Areas.FieldValues['BalanceHours']:=BalanceHours;
    dataObj.EQ_Areas.FieldValues['CompletedCosts']:=CompletedCosts;
    dataObj.EQ_Areas.FieldValues['CompletedJobs']:=CompletedJobs;


    dataObj.EQ_Areas.post;


    Application.CreateForm(TF_ProjectMain,F_ProjectMain);
    F_ProjectMain.show;


    Except

    On E: Exception do
        Begin
        EMessage('Error Updating Project Areas - ' + E.Message);
        canclose:=False;
        end;

    end;

    wait(False);

  end;

0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9904426
>Does anyone know of anytool that can show how much
>of the stack has been consumed/free?

not really, but
i would advice you to use madExcept from madshi
see www.madshi.net

now looking at your code ;-)

meikl ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9904462
just wondering about this part

....
  Application.CreateForm(TF_ProjectMain,F_ProjectMain);
  F_ProjectMain.show;
....

guessing F_ProjectMain is not the app-mainform,
and there is no instance already present

guessing also TF_AreasMain is not the app-mainform

is this correct?

meikl ;-)


   
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9904662
Hi meikl ;-)

Correct F_ProjectMain is not the app-mainform - the main form is the Splash which is hidden.

The code doesnt even get there - it doesnt even seem to run at all when the stack error occurrs.

Strangely I can add recs to the record sets and scroll around them - allsorts of things and can safely exit.  However if I do the sorting I sometimes get the error - I could not absoulutely say whether this is causing it.

The error is totally unpredicable - I have tried changing the controls for others etc in case there is some recursive calling in the VCL somewhere.

The only thing I cant change is the TQueries - they are EasyTable controls - I am trying to identify if the problem is there.

Voodooman
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9904740
well, just download madExcept at
www.madshi.net

a little description can be found
http://help.madshi.net/madExcept.htm

i use it also, if i had problems like yours

meikl ;-)

0
 
LVL 12

Expert Comment

by:andrewjb
ID: 9904751
You didn't reply - are you running in the debugger or as a standalone. Doesn't running under the debugger trap the stack overflow and let you look at the stack trace?
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9904981
Hi andrewjb

Sorry not to reply to you directly - I have been out to a client whose ISP (a big Telco) has decided to ditch its named SMTP Server today without telling its millions of customers who have been using it....they forgot to tell anyone...

I am running in the debugger. It doesnt help - I can run thru the same code a hundred times and nothing happens.  

Also I cant seem to find the execution point. The 'Show execution Point' menu is permanently greyed out.

When I put the breakpoint on the first available line of the close query - it doesnt  even get there.

I am still trying to figure out this Delphi Debugging stuff - its more 'Under the Hood' than I am used to! I found the Stack Call window in the Delphi Bible last night about 2.30am but I havent had the probel today!

Voodooman

0
 
LVL 5

Author Comment

by:Voodooman
ID: 9905001
Hi meikl ;-)

Thanks for the input I have downloaded MadExcept and Installed it - guess I have some learning to do about Delphi Exceptions....

Thanks Everybody who has helped so far

Voodooman
0
 
LVL 12

Assisted Solution

by:andrewjb
andrewjb earned 100 total points
ID: 9905049
Just to make sure...

Your project options have got optimisation turned OFF, all the bits under debugging turned ON, build with runtime packages OFF, then a full rebuild of the whole project.

When you put in the breakpoint, you do get a red dot, don't you. It remains red whilst you're running?


Hope I'm not being rude - it sound like you haven't used Delphi much, so you might be buliding with duff options for debugging...
0
 
LVL 17

Assisted Solution

by:Wim ten Brink
Wim ten Brink earned 50 total points
ID: 9905226
Increasing the MAXSTACKSIZE might just make the system wait longer before it crashes. In my experience, a stack overflow is often (almost always) caused because of an endless loop or a recursive method that never ends. The last thing is more likely.
Maybe you're just walking through the table without moving to the next record. (Forgetting to call Table.next in a loop is quite a common error.)

So, check your loops, check to make sure you're not calling a method recursively. That last thing might be a bit difficult in an event-driven environment because event1 could trigger event2 which triggers event1 again, thus resulting in an endless loop.
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9905718
Hi andrejb

Of course you are not being rude - if I cant take the answer I wouldnt ask the question!!

I have turned off optimisation (it was on) - why should I turn it off?

All the debug options are turned on apart from debug DCU's which the help says are for CLX and so I guess I shouldnt use them.

As far as the Runtime Options are concerned I have to use runtime packages as I didnt buy the source for some of the tools I am using.

You are correct I havent used Delphi much since 94/95 (Ver 1 and 2).  I have been working as a contractor with VB and SQL Server as an Analyst Programmer and SQLServer DBA (20 million+ records and 500+ seats).

Delphi looks better, runs faster, has some brilliant tools that are unbelievably cheap (try buying tools for VB) and makes small programs + choice of database.

The downside of Delphi is that you never get under the hood in VB and 'Just in Time Debugging' in VB is a massive advantage with big programs (120k plus lines).  I cant imagine building a massive business critical sytem in Delphi - it would seem impossible.

I have built a great looking commercial program (resolution independent etc).  I would like it to be 'Bullet Proof' when I sell it.

Thanks Again

Voodooman
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9905854
Hi Workshop_Alex

You are of course 100% right when you say that it might just take longer to crash the program.

However

I am 99.9999% confident I am not doing any recursive calling and I am doing no looping at all.

Interestingly I have been trying to find the max stack size in VB - but cant find anything definitive.

Of Course various controls could be making recursive calls that I have no knowledge of....

Voodooman
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9911142
Dear Experts

I am somehow getting to the bottom of this!

It is not helped by the erratic nature of the errors.  I have traced the problems to erratic behaviour concerning the use of a data module and the TQuery components (in my case TEasyQuery).

Problems are occurring when I use this (I got this from a book - dont blame me!).

Application.CreateForm(TF_AreasMain,F_AreasMain);
F_AreasMain.show;

procedure TF_AreasMain.FormClose(Sender: TObject; var Action: TCloseAction);

  begin

  Release;

  end;

Its the 'Release' that appears to be somehow attempting to free the recordsets in the datamodule - the data module appears to be attempting to re-instate them - recursively - causing a stack overflow. It might be because I have the recordsets in the data modules and some (not all) datasources on the forms.

I guess if my data controls were on the form I would not be having these problems - trying to hard to do the right thing seems like a bad idea!

Its looking like using Auto Create and just Closing the forms may be the answer. I will be out allday - I will allocate the points tomorrow after reading any comments.

I dont think Auto Creating all the forms matters today with 128mb memory being common - VB never unloads a form once its been loaded (apparently unload never frees the resources in VB) and I have a product with 140 forms that runs no problems.

Thanks all you Delphi Experts

Voodooman
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9911167
instead of
procedure TF_AreasMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Release;
end;

use

procedure TF_AreasMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

meikl ;-)
0
 
LVL 5

Author Comment

by:Voodooman
ID: 9919249
Hi Experts

Your help has given me the answer I am going to split the points if thats OK.

My problems seem to be solved at last.  They began after I did a big 'Tidy up' operation on the Code and moved most of my recordsets and some but not all of the datasources to my data object - I like to compartmentalise as much as possible - it helps maintain it later.

Since then I have had bizarre unreliability problems such as 'unable to update a read only recordset' - that was not a read only recordset a minute ago, random Exceptions in the IDE,  radom stack overflow errors. All very random and not reproduceable on demand.

Cause - Use of 'Release' Keyword in the Close method of Data Centric Forms where datasets and sources are remotely located in the 'data object'.

Workshop_Alex - on the money - there is only one way to get a stack overflow - recursive calls- 50.

AndrewJ - changing the debug settings made tracing the problem possible - 100

Kretzschamar - focussed my attention on the Events - Close and Query Unload - 100

Thank you all very, very much - this has been driving me crazy - at least 80 hours wasted and my project 2 weeks behind.

Merry Xmas

Voodooman

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

695 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question