I have an ongoing TurboPascal development that jumps into one of the units code on program termination causing a hangup. Running it in the IDE under Windows XP 'Just' locks up the instance of the Turbo compiler. Porting it to another machine running Win98 gives 'Code segment to large' when compiling so rearanging the units to get it to compile and then running it gives "This program has performed an illegal operation" from Win98. In finality the program will run under DOS but I was very suprised at the different behaviour between XP and Win98. The XP compiled version hangs up on exit on a DOS machine. Any hints at where to look to sort this out would be appreciated.

Regards,
Gammatech

Recommended Answers

All 7 Replies

First question is: What version of Turbo Pascal? This could make a great difference. For instance, in ver 6 and earlier, the editor would only hold 64K of text, limiting the size of programs, and causing the need to break up code into sometimes non-intuitive chunks.

Also, the order of entry/exit of units is like this: First unit initializes, (possibly) causing other units to initialize in turn. During finalization (exit), the unit code is executed in the reverse of the initialization. It's basically like a big stack that's pushed on init, and popped on finalization.

This could be the source of some of your problems. Unit finalization is always executed, even if it's not explicitly coded. As you can tell by re-arranging the units and getting different symptoms. Slightly off-topic: One of the interesting things about units is that you cannot have circular unit references in the interface section, but you are allowed circular unit references in the implementation section. Sometimes, moving units that are not absolutely needed at the top, to the bottom of the unit solves many problems.

Use your debugger. You might have to start stepping from the very beginning of your program. If it's heavily object-oriented, this can be a true pain. Judicious use of breakpoints helps, if you can figure out where to set them. The technique known as "half-stepping" helps tremendously here.

The differences in program exit behavior can be attributed to the different versions of OSs you've run the program on. WinXP does a much better job of "virtualizing" programs so that, if something goes wrong in one program's memory space, that program can be killed and the memory reclaimed without crashing the entire machine. Mostly this works. Win98 is much more primitive, and the "This program has performed an illegal operation..." message is about as generic as you can get, and provides no real help in diagnosing a problem. You may also end up crashing the machine.

DOS (as in versions 2.1 to 6.2), on the other hand, is so primitive that it's quite robust. Sometimes, you might actually have a problem with a program, but have no idea what, or even that a problem exists.

So, to sum up:

  1. Break your main program into smaller chunks (units).
  2. Re-arrange your units.
  3. Use the debugger to step through to the spot where things break. Sometimes having just this little piece of information answers all kinds of questions.

I hope some of this helps, but without having slightly more information to go on, all I can offer is generalities.

Daaave

Thanks Daaave,

I'm running turbo pascal version 7. My program has been broken up into quite a few units (16 bespoke plus Graph,Dos & CRT) the modified version of CRT is used to avoid crashes on faster machines. Eight of the units have specific initialisation routines so setting breakpoints enables me to sort out the order that they initialise. ie 15th, 8th, 10th, 9th, 1st, 4th, 7th, 6th. I was surprised to find that they do not initialise in the order they are listed in the USES clause of the main program. 5 of the units have exit routines and again by setting break points I was able to track the exit chain. As expected it runs in the reverse order of initialisation but at the end of the last exitproc it jumps into the middle of one of the procedures of that unit!

You say that re-locating a unit to the end of the list may impove things but as it seems to initialise in an order that I dont seem to have control over how do I know which is the end?

One point, as the program has grown over many years it is not very modular, indeed many of the units call other units in their USES clause.

The program always runs stand alone on a DOS machine and is usually running 24/7 as it is monitoring a production process. Until this latest program extension to include a number of extra facilities it seemed to run and exit reliably.

Thanks again

Gammatech

send me a code on how to add numbers in delphi

i am using delphi 5 and need to know how i can write a program to add two numbers

Here is another thing which might be of use. I have seen instances where a program jumps to unexpected code as it is shutting down. For instance, Delphi may the OnActivate event of an open form even when the program is terminating. Apparently, the form needs to become active before it can be closed. There is an easy way to block that kind of behavior - before the first line of the problem code include the line
if Application.Terminated then EXIT;
That will prevent the rest of the code from executing. Not an elegant solution, perhaps, but it helps.
Good luck

send me a code on how to add numbers in delphi

1+2

HOPE THIS HELPS LOVE PTY

I have an ongoing TurboPascal development that jumps into one of the units code on program termination causing a hangup. Running it in the IDE under Windows XP 'Just' locks up the instance of the Turbo compiler. Porting it to another machine running Win98 gives 'Code segment to large' when compiling so rearanging the units to get it to compile and then running it gives "This program has performed an illegal operation" from Win98. In finality the program will run under DOS but I was very suprised at the different behaviour between XP and Win98. The XP compiled version hangs up on exit on a DOS machine. Any hints at where to look to sort this out would be appreciated.

Regards,
Gammatech

Maybe do a find to see the places that the method causing the problem is called from? I'd place breakpoints before the calls (if there aren't too many!) and trace it that way. It shouldn't be too difficult to find the problem if you work backwards towards it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.