I have a large, complex application written in C++ (no MFC or .NET). The client that uses the software most aggressively will, within an hour or so of starting it, get to a state where all the windows stop painting. We get reports that the application has "hung" because as far as they can tell nothing is happening. In reality, the application is functioning, just not displaying anything.
I've tried a lot of different things to no avail. I'm out of ideas...
You probably already have a hunch of what it is - you give it away in the first sentence
... large, complex application ...
It sounds like you have a GDI resource leak somewhere. To confirm this try looking in task manager at GDI objects for your process. At some point most GDI operations will fail for your application.
Make sure you are freeing all handles correctly. Note that different GDI objects require different methods of freeing the object. For example GetDC is freed by ReleaseDC, but CreateDC is freed by DeleteDC.
This is why RAII smart objects (like smart pointers) are recommended for resource management in C++ (where freeing is managed by the smart object to reduce the likelihood of leaks and errors).
I'd bet that the application is leaking GDI objects, and when the GDI dedicated space for this process is exhausted, it can no longer paint itself.
You can check if this is the case by adding to the Windows Task Manager (or any other process manager such as Process Monitor) the column GDI Objects and see if this number grows unbounded with time.
Your application may actually be suffering from an exception that is getting ignored. See Microsoft KB article 976038.
Related
I have an MFC application developed with VS2003
It is working fine in XP vista etc.
But when i have executed it in windows 8, and we use it for some time,
then no window is displayed. Instead of that the a MessageBox with a message 'Out of Memory' is displayed. And the Message box is Having the caption of my application.
This issue is rarely occurred in windows 7 too.
I have tried watching the handles using tools like processexplorer and it is not increasing.
Also many forums says that it is because of increase in unclosed handles or resources.
Can any one suggest how can i find where the issue is. Or any one provide possible reason for this.
I cant setup the devenv in the machine causing the issue. I am confused how to diagnose by executing a test build in that.
Please provide your findings.
Thanks in advance.
You clearly have a memory leak somewhere. It's hard to be any more specific without seeing the code.
A debugger is really the best way to solve this problem. If you can reproduce the problem on your development machine, that would be the easiest case. If not, you can attach a debugger to the running process on another machine, either locally or remotely.
The MFC libraries also support some basic memory leak detection, turned on by default for Debug builds and controllable for other builds using the AfxEnableMemoryTracking function. You can use this feature to obtain information about which blocks of memory were allocated but not properly deallocated (i.e. were leaked).
Like you mentioned, Process Explorer is another good way to track down resource leaks. Are you sure that the handle counts are remaining constant rather than trending upwards over time? If the values in the columns are never changing like the question suggests, then you are surely doing something wrong. Your application has to be creating objects in order to do its job. The point is to make sure that it disposes of them when it is finished.
If you can't reproduce the problem with the running application and have only the source code available, you'll need to go through the code and make sure that every use of new has a corresponding use of delete (and that new[] matches up with delete[]). And in general in C++, you should avoid explicit dynamic memory allocation wherever possible. Instead, use the container classes that are provided either by MFC or the standard library. For example, don't allocate arrays manually, use std::vector to do it for you. These container classes ensure that the memory is automatically deallocated in the destructor when the object goes out of scope.
I am creating one game in Windows phone using c# and silver light platform. I am new in this technology and currently facing memory leak issue.
As per research and study I have done, I have tried to do all the things including events, string and usage of garbage collector.
Can any one please give common tips to best utilize garbage collector and memory management since it seems issue right now. When my garbage collector reaches 5 lac size, it stop collecting new things and application is getting crash.
I also tried empty the garbage collectore passing parameter 0 in gc collect but it is crashing the app.
Can you please guide and help for basic things to take care, process to follow to avoid such issues and best use of GC collect?
Thanks in advance,
Jacob
In general, you should never have to call GC.Collect yourself as unused objects will be automatically collected every few seconds.
As for what can prevent objects from being collected, it comes down to them being "rooted". Roots include:
Any static references
Any references held by the run loop (your Application is the closest thing here)
Anything being displayed on the current page or any page behind it
Anything referenced by any of the above (including UI events), or referenced by anything that is referenced by any of the above (etc).
In the above scenarios, those objects and any objects they hold a reference to cannot be GC'd. So as for advice:
Avoid defining anything as static
Be careful how many objects are held by Application
Avoid a navigation model that allows your back stack to grow to ulimited levels
Potentially look at setting references to large data sets to null in your page/viewmodel's OnNavigatedFrom method and re-initialise them in OnNavigatedTo
I'd recommend using the Windows Phone Profiler, which comes with the 7.1 SDK. It will tell you what objects are in memory and why.
Without seeing any of your code, it is difficult to give specific advice.
However, I strongly suggest you run a memory profiling tool like ANTS Memory Profiler or .Net Memory Profiler. These tools will show you what portions of your code are never released and are very helpful in making the adjustments that you need.
Recently I have been reading up articles about DLL injection and I understand them fairly well.
However, what I don't understand is why APIs such as CreateRemoteThread, WriteProcessMemory(in being able to write to the memory of another process) and VirtualAllocEx(in being able to allocat memory in the context of another process) were implemented in the first place.
What was the original need for such APIs? Just curious.
WriteProcessMemory was made for ring3 debuggers that need to securely write process memory, most commonly for INT 3 breakpoints or user provided memory edits.
along the same line, CreateRemoteThread can also be used for debugging purposes, however, MSDN can enlighten us on CreateRemoteThread a bit more:
A common use of this function is to inject a thread into a process
that is being debugged to issue a break. However, this use is not
recommended, because the extra thread is confusing to the person
debugging the application and there are several side effects to using
this technique:
It converts single-threaded applications into
multithreaded applications.
It changes the timing and memory layout of
the process.
It results in a call to the entry point of each DLL in
the process.
IIRC, CreateRemoteThread is also used by debuggers to hook application native expection handlers, commonly set by SetExceptionHandler, which requires call from the target process as the handler is stored in the PEB.
VirtualAllocEx is just how windows virtual memory system operates, it needs a context to allocate in, be it in the current process, a child process or a remote process. VirtualAlloc in fact is nothing more than a pass through wrapper of the Ex variant, it just passes a special constant that indicates the handle of the caller process is to be used.
My delphi program (NOT for .NET) on windows 7 seems to be running for couple of days straight and then the program sort of freezes with all of its windows painted with blueish grey color as if its windows are disabled. You simply don't have control over the program anymore but has to kill its process and start it up again. You don't need to reboot the system itself.
Has anyone experience this or anything similar? If so, what did you do to resolve or try to resolve it?
Thanks,
Your question context is very vague. We do not have any information about your application, even its design and architecture.
Nethertheless, my (general-purpose) suggestions are the following:
If your application is not multi-threaded, do the process in background threads, then leave the main thread ready to process GDI messages;
If your application is multi-threaded, take care that all VCL access from background threads are made via a Synchronize call;
If your application is multi-threaded or use timers, take care that no method is re-entrant (in some circonstances, you may come into a race condition);
Hunt any memory leak;
Use a detailed logging of the program execution, logging all exceptions risen, to guess the context of the program hang (it may be used on the customer side also to hunt race conditions);
Download the great free tool named ProcessExplorer (now hosted by Microsoft), and check out the state of your frozen program: you will see detailed information about threads, CPU use, memory, network, libraries, handles - this is a must have for any serious debugging - track especially the GDI handles leaks (number of those should remain stable);
If you did not check it already, take a look at the global Windows system event log: there may be some information here;
Perhaps a third party component or library is responsible of the process hang: try to isolate the part of your code which may be responsible of this hang.
I've Delphi application running for months without any problem. Issue is definitively in application code, not in the Delphi architecture (its RTL and VCL are very stable).
The bluish grey color is probably the default window color, meaning the window is no longer painting itself. This is consistent with the other symptom that the program no longer responds to any input. This means it isn't processing any window messages.
The easiest way to debug is to run the program in a debugger, and when it's hung just stop it and see where it's at.
If you have a memory leak you may eventually run out of memory in your process space, and it's possible that the program doesn't properly respond to that condition. Check Task Manager to see the amount of memory it's using.
Yes I fixed several hangs and other problems in the past years.
I used ProcessExplorer before (to view the stack), but it needs Microsoft debug symbols. And with Delphi you can only create a .map file. With map2dbg I could convert the .map to a .dbg, but this does not always work (note: .dbg is deprecated, newer versions of Microsoft debugging tools do not use them anymore).
So I made my own tool :-)
It is part of "AsmProfiler Sampling" tool:
http://code.google.com/p/asmprofiler/downloads/detailname=AsmProfiler_Sampling%20v1.0.7.13.zip
Click on the "Stack view of Process" button in the first screen.
Then select your process from the list and double click on it:
http://code.google.com/p/asmprofiler/wiki/ProcessStackViewer
Now you can view the stack trace of each thread. If the GUI does not respond, the main thread hangs, so check the first thread. (note: sometimes you see an "emtpy" stack because a function misaligned the stack for calculation etc, use the raw strack tracing algoritm to get more the full stack again (with a lot of false positives, because every pointer on the stack which is possible a function is shown!)).
Please post the stack here if you can't solve it, so we can take a look at it.
Note: it uses the jclDebug.pas unit of the JEDI library, so it can read .map and .jdbg files (also .dbg and .pdb debug files of Windows dlls) and also internal JCLDEBUG sections (embedded .jdbg file in one .exe). So you must at least build an .exe with detailed (!) map file, see Project Options -> Compiler -> Linking.
My Win32 console applicaton uses a third-party library. After it exits WinMain global objects destruction begins and an AV happens somewhere deep inside. I'm really tempted to just write
TerminateProcess( GetCurrentProcess(), 0 );
somewhere near the end of WinMain. If I do this the application ends gracefully.
But MSDN says that doing so can compromise the state of global data maintained by dynamic-link libraries (DLLs) which is not clear. I understand that if I have some global object its destructor is not run and I risk not finalizing a database connection or something similar. I don't have anything like that in my program.
What exactly is the risk when using TerminateProcess? How do I determine if I can use it for my purpose?
Based on the documentation for that and ExtiProcess it seems the primary concern is that DLL's are unloaded without a call to DllMain with the flag DLL_PROCESS_DETACH.
My 2cents: The documentation is being paranoid that you will upset some critical operation which runs in DllMain + DLL_PROCESS_DETACH. Anyone who depends on that to maintain critical state is already at the mercy of task manager so I don't see a huge risk in using this API.
Generally the bad things will happen when interacting with objects outside of your process. For an example say you have some shared memory used by multiple processes that your process will write to and other processes read and or write to. Typically to synchronize the reading and writing a mutex is used. If a thread in your process has acquired the mutex and is in the middle of making changes when TerminatePorcess is called, the mutex will be abandoned and the shared memory potentially left in an inconsistent state.
I suspect you are miss using one of the third party libraries. DllMain is somewhat limiting so the library may have initialize and uninitialize functions that you are supposed to call.
AFAIK, if you're not doing anything "fancy" (which includes but is not limited to: creating threads, locks, DB connections, using COM objects), nothing terrible will happen. But as Earwicker says, you don't know what OS-wide stuff a DLL is doing, and you certainly don't know if that will change in the future, so relying on this is very fragile.
Aren't you curious to know why this access violation is occurring? It may well be the sign of something that became corrupted much earlier on. Please at least confirm that the bug is caused by this 3rd-party library, e.g. by writing a program that links with the library but whose main() does nothing, and confirming that this causes the same crash.
It depends how you interpret "global data". If you take it to mean (as I normally would) data stored in the process's address space, then the advice makes no sense - we know that memory is going to disappear, so who cares what happens to that?
So it may be referring to OS-wide stuff that a DLL may have done, that persists outside the lifetime of any process. A simple example would be a temporary file that might need to be cleaned up; crash the process too many times and you'll run out of disk space, so probably best not to make a habit of it.