Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ON SHUTDOWN

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB

I have an application which runs on a user’s site. The starting point for the application is a program main.prg. This is bound with all the other forms, class defintions &c into – say - XYZApp.exe

The program main.prg initialises variables &c before creating a ribbon menu (a toolbar object) which controls the application.

main.prg does other initialisation and then issues the instruction ON SHUTDOWN DO SystemExit before calling DO EVENTS. The SystemExit function is coded lower down in main.prg.

The Toolbar menu then controls the application (maybe for hours !).

When the user decides to close the application (by clicking on a exit button on the menu bar), a CLEAR EVENTS instruction is issued; control passes back to main.prg which tidies a few things and RETURNs. The application then closes.

This generally works fine; there is also an error routine (ON ERROR DO ErrorRoutine) which is invoked when (in operation) any of my numerous bugs is encountered. This writes out to a log file Errorlog.txt details of variables, program line numbers &c

Occasionally I am seeing in the Errorlog.txt file on the user’s system that ‘File Systemexit does not exist’ The user has not complained, but I have not been able to discover why this is happening. I can certainly invoke the SystemExit() function on my development machine, by clicking on the x button in the top right of the window when the appplication is runnng.

(The only reference to SystemExit is from the ON SHUTDOWN statement)

Grateful for any suggestions as to why SystemExit is sometimes becoming unavailable.

Thanks. Andrew
 
Andrew,

You should also clear ON SHUTDOWN immediately after CLEAR EVENTS. Otherwise, other problems could occur. In your main.prg, put the following:

<code before READ EVENTS>

READ EVENTS
ON SHUTDOWN

<code after READ EVENTS>

You may consider putting the SystemExit function in another .prg
 
Andrew,

I favor Vernpace's solution. What is the code in your systemexit procedure?
Does your ErrorRoutine also list the stack? If so see if systemexit is called.
Stay healthy,

Koen
 
The OP says he is using DO EVENTS which is odd.

I don't call READ EVENTS, I think I rely on presenting a modal form and working from there.

All I have in my on SHUTDOWN DO GOODBYE is QUIT...

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Thanks Nigel

Code:
on shutdown do systemexit in main.prg

I can certainly try that. Will have to see whether that fixes the problem. Unfortunately it is difficult to test, because when I invoke Shutdown by closing the application's window (running XYZapp.ex on my own development machine), that works fine with the existing code.

I have even put a Messagebox() instruction in so that you can see that the SHUTDOWN event has invoked SystemExit.

So it is difficult to test, but your advice will not do any harm; will have to see whether the error still occasionally happens on the user's site.

and Thanks, Vernpace. There is indeed an ON SHUTDOWN after READ EVENTS. I believe that is normal practice, but thank you for mentioning it.

Finally, Thanks Koen. The error routine does indeed list the stack, showing the name of each routine and the line number within it. On this occasion the stack is empty: the error report does not show any parent routine calling SystemExit().

The SystemExit() function mainly saves the current state in which the user left the application, in a table settings.dbf. It releases several global objects which have been used in the application and finally does ON SHUTDOWN

Very grateful for the time you have all given to this. Andrew
 
You are quite right, Griff. The instruction I use is READ EVENTS.

 
Andrew,


Andrew said:
On this occasion the stack is empty: the error report does not show any parent routine calling SystemExit().

that is odd , I believe there is something wrong here, as the callstack cannot be empty, unless you have some code to clear it.
I would advise you to put a 'set step on' as first line in your SystemExit() procedure and than see what the callstack actualy is.

Stay healthy,

Koen
 
Very grateful for your help, Koen.

You have prompted me to look at my ON ERROR routine . . . Years ago I decided that the first entry on the stack always showed information which was duplicated in other stack entries : it just told me which form the error came from, and that was apparent in the lower stack entries.

So my ON ERROR included code like :

Code:
   .  .  .
   ASTACKINFO(MyStack)
   lnMax = ALEN(MyStack)/6 - 2
   FOR I = 2 TO lnMax
      lcString = lcString + PADR(MyStack(I,3),45) + ;
            "Line " + LTRIM(STR(MyStack(I,5),4)) + lCRLF + ;
            "        " + LTRIM(MyStack(I,6)) + lCRLF
      NEXT I

I now realise that I should start with FOR I = 1. Will do that and hope to find out a little more when the ON SHUTDOWN error happens again.

Thank you for your patience!

Andrew
 
Andrew,

I am working with following code in my Errorlogging:

Code:
* New 6-15-2007 jjh
* Use aStackInfo to show deep detail
* ------------------------------------
lsStack = 'Call Stack (Descending)' + m.lcNline ;
+ Replicate('-', 23)
For i = Alen(m.aStk, 1) - 1 To 1 Step - 1
* I named each element to make it easier to understand (jjh)
	lcCurPrg  = m.aStk(m.i, 2)
	lcModule  = m.aStk(m.i, 3)
	lcSource  = m.aStk(m.i, 4)
	lcModLine = Transform(m.aStk(m.i, 5))
	lcSrcCode = m.aStk(m.i, 6)
*
* Create a line of info
	lsStack = m.lsStack + m.lcNline ;
	+ m.lcModule + ' (Line: ' + m.lcModLine + ') ';
	+ '{' + m.lcSource + ' ' + m.lcCurPrg + '}' ;
	+ Iif(Empty(m.lcSrcCode), '', + m.lcNline + '  Code: ' + Alltrim(m.lcSrcCode))
Endfor

This will produce following in my Errorlog:

=========================================================
Call Stack (Descending)
-----------------------
rtfshortcut (Line: 28) {d:\foxproprojects\stolpersteine\menu\rtfshortcut.mpr d:\foxproprojects\stolpersteine\menu\rtfshortcut.mpx}
Code: DEFINE BAR 1 OF shortcut PROMPT "Find first occurance" PICTURE "zoeken.png"
frmnaam1.pf.page3.cntrtfedit1.cmdsearch.click (Line: 2) {d:\foxexamples\rtf\vladimir\rtfedit.vct d:\foxexamples\rtf\vladimir\rtfedit.vct}
Code: DO RTFshortcut.mpr
program1 (Line: 24) {d:\foxproprojects\stolpersteine\progs\program1.prg d:\foxproprojects\stolpersteine\progs\program1.fxp}
Code: Read Events
dofirst (Line: 65) {d:\foxproprojects\stolpersteine\progs\dofirst.prg d:\foxproprojects\stolpersteine\progs\dofirst.fxp}
Code: Do program1

As you can see it goes way up to program1, from the menu (where the error was created)

Stay healthy,

Koen
 
For what it's worth, here is the bit of my error routine that deals with the stack:
Code:
* Get details of calling stack
lnStax = ASTACKINFO(laStax)
lcCallingStack = ""
FOR lnI = lnStax TO 1 STEP -1
	* Ignore anything in the error handler itself
    IF INLIST(LOWER(laStax(lnI, 3)), "errorroutine", "on...")
      LOOP
    ENDIF
    lcCallingStack = lcCallingStack + SPACE(5) +  ;
          + laStax(lnI, 3) + " (line " + TRANSFORM(laStax(lnI, 5)) ;
          + ")" + CHR(13)
ENDFOR

I'm not saying that this is any better or worse than anybody else's, but I thought it might be of interest.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top