The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Delphi program dying without a whisper

We've got a Delphi 6 application that sometimes dies without raising any kind of exception, the application just closes as if it had been shutdown. We even added an exception handler (EurekaLog) to see if we were missing something but it still happes.

Some context: the application can use a lot of memory (half gig or more) and runs a Windows 2000 Terminal Server which can have several instances of it.

Any ideas on how to trap the potential conditions for an application dying without leaving any kind of trace or exception?
Wednesday, November 21, 2007
Sounds like you are running out of memory and Terminal Services is just killing the process to prevent the server from going over.

Assuming you are not using the 64bit Windows 2000 Advanced edition, so it's 32 bit and it's max addressable memory space is 4GB of which typically 3.25GB is usable in Windows...

half a gig * 7 = 3.5GB.

Yep, out of memory.

Solution: move to 64bit OS with as much memory as you need.
Thursday, November 22, 2007
This is C++ knowledge so it's probably useless to you, but in C++ a program can exit by calling the exit() API; you can detect this using the atexit() API. If an exception is thrown while an exception is being thrown (which can easily happen if a destructor is allowed to throw an exception), it will invoke the terminate() API which won't even call the atexit() handlers: you can redirect terminate() to a user-defined function by using the set_terminate() API. See also the abort() and unexpected() APIs. You might want to verify that your destructors don't throw exceptions.
Christopher Wells Send private email
Thursday, November 22, 2007
> half a gig * 7 = 3.5GB.

Is that true, or is the limit per-process? I would have guessed (I don't know) that the address-space limit is per-process (and that 'extra' data for other processes can be paged-out to the swap file).
Christopher Wells Send private email
Thursday, November 22, 2007
Christopher is right--there are a few ways to shutdown without leaving a trace, and exit is often involved.  I don't know much about Delphi, but if you're using any external DLLs, 3rd party components that might use a DLL, etc then one of them might be calling exit.

I was having this problem a while back so I wrote some code to catch all exceptions/exits.  You have to call down to Win32 and the C runtime library, but _everything_ gets caught.

I call all the following to capture everything:


The nice thing is, once you catch one of these you can call MiniDumpWriteDump to create a crash dump of the application for loading into a debugger (at least it works great with Microsoft debuggers).
Thursday, November 22, 2007
Is there anything in the event log?
Thursday, November 22, 2007
Blowing the call stack on windows will cause the behavior you describe, if you don't use a structured exception handler.
Thursday, November 22, 2007
Doug's suggestions are good.

You might want to check whether DEP (Data Execution Protection) is enabled, especially if you are using some wrapper software for trial protection.
Tony Edgecombe Send private email
Friday, November 23, 2007
+1 for checking the DEP. You sometimes won't see the error unless you're logged in as an Administrator on the actual server (not a Terminal Server Session).

Best bet is to turn off all instances of your program and just turn off DEP for your program.
Wayne Bloss Send private email
Saturday, November 24, 2007
Don't know if you have this solved yet or not, but if not you might add MadExcept (, IIRC) to your app. It hooks in before the standard error handling stuff does, and can provide stack traces and other debugging info.
It's easy to toggle on and off, too.
Ken White Send private email
Monday, November 26, 2007
> half a gig * 7 = 3.5GB.


Each process gets its OWN virtual address space.  On a 32 bit Windows machine, by default (1) the address space is 4GB wide.  2GB is for "user mode" (your program) and 2GB is for the kernel.

Practically speaking, I've found that a program can allocate about 1.5 GB before it dies.  If the program is constantly allocating and deallocating larger chunks of memory, it is plausible that an allocation for something as large as half a GB would eventually fail because a contiguous address range is not available.  Think heap fragmentation.

(1) Windows servers can run with a /3GB switch that lets user programs have a 3GB address space.
Meganonymous Rex Send private email
Tuesday, November 27, 2007
I have the very same problem, but my application have a small memory requirement. It simply disappears, without any notice.

I simply can't trace it, even using MadExcept...

Any other thoughts?
Moreno Send private email
Tuesday, November 27, 2007
can it be that the excepton gets eaten
something like

Wednesday, November 28, 2007

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz