I'm maintaining an MFC application in some points it stop responding for 30 seconds , some times 1 minute or more. I'm supposed to fix that issue, I tried tracking the code[all methods in this class] and also the issue is still, I tried to pause debugging during this time and I got nothing as in this image
I want to know how to track the code that cause the application to stop responding
add watch variable for any separate thread event
increment each watch variable inside its thread
also very useful can be flag if the thread/event is executing (especially for events)
you must set this flag on enter
end clear before exit
visualize watch variables somehow.
either use some debug print inside your App.
or use separate Window
or even better separate App connected with any IPC method. (this will work even if your App UI hangs)
When the app hangs just see which variables are incrementing and which not
with flags you can determine exact what is hanging up on you ...
Good luck with debuging.
Related
Hello I am looking for a signal for gtkmm. Basically I am doing some simulations and what I want is something like this :
I assume I do 5 simulations :
progressBar.set_fraction(0);
1 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
2 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
3 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
4 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
5 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
But I don't know which signal I have to use and how to translate to this.
Thank you a lot for your help !!!
The pseudo code which you presented in your question should actually work - no signal is necessary. However, you could introduce a signal into your simulation for update of the progress bar. IMHO this will not solve your problem and I will try to explain why and what to do to solve it:
You provided a little bit too less context, so, that I will introduce some more assumptions: You have a main window with a button or toolbar item or menu item (or even all of them) which start the simulation.
Let's imagine you set a breakpoint at Gtk::ProgressBar::set_fraction().
Once the debugger stopped at this break point you will find the following calls on the stack trace (probably with many other calls in between):
Gtk::Main::run()
the signal handler of the widget or action which started the simulation
the function which runs the five simulations
and last the call of Gtk::ProgressBar::set_fraction().
If you could inspect the internals of Gtk::ProgressBar you would notice that everything in Gtk::ProgressBar::set_fraction() is done properly. So what's wrong?
When you call Gtk::ProgressBar::set_fraction() it probably generates an expose event (i.e. adds an event to the event queue inside of Gtk::Main with a request for its own refresh). The problem is that you probably do not process the request until all five runs of the simulation are done. (Remember that Gtk::Main::run() which is responsible for this is the uppermost/outmost call of my imaginery stack trace.) Thus, the refresh does not happen until the simulation is over - that's too late. (Btw. the authors of Gtk+ stated somewhere in the manual about their cleverness to optimize events. I.e. there might be finally only one expose event for the Gtk::ProgressBar in the event queue but this does not make your situation better.)
Thus, after you called Gtk::ProgressBar::set_fraction() you must somehow flush the event queue before doing further progress with your simulation.
This sounds like leaving the simulation, leaving the calling widget signal handler, returning to Gtk::Main::run() for further event processing and finally coming back for next simulation step - terrible idea. But we did it much simpler. For this, we use essentially the following code (in gtkmm 2.4):
while (Gtk::Main::events_pending()) Gtk::Main::iteration(false);
(This should hopefully be the same in the gtkmm version you use but if in doubt consult the manual.)
It should be done immediately after updating the progress bar fraction and before simulation is continued.
This recursively enters (parts of) the main loop and processes all pending events in the event queue of Gtk::Main and thus, the progress bar is exposed before the simulation continues. You may be concerned to "recursively enter the main loop" but I read somewhere in the GTK+ manual that it is allowed (and reasonable to solve problems like this) and what to care about (i.e. to limit the number of recursions and to grant a proper "roll-back").
What in your case is the simulation we call in general long running functions. Because such long running functions are algorithms (in libraries for anything) which shall not be polluted with any GUI stuff, we built some administrational infra structure around this basic concept including
a progress "proxy" object with an update(double) method and a signal slot
a customized progress dialog which can connect a signal handler to such a progress object (i.e. its signal slot).
The long running function gets a progress object (as argument) and is responsible to call the Progress::update() method in appropriate intervals with an appropriate progress factor. (We simply use values in the range [0, 1].)
One issue is the interval of calling the progress update. If it is called to often the GUI will slow down your long running function significantly. The opposite case (calling it not often enough) results in less responsiveness of GUI. Thus, we decided for more often progress update. To lower the time consuming of GUI, we remember the time of last update in our progress dialog and skip the next refreshs until a certain duration since last refresh is measured. Thus, the long running function has still some extra effort for progress update but it is not recognizable anymore. (A good refresh interval is IMHO 0.1 s - the perception threshold of humans but you may choose 0.05 s if in doubt.)
Flushing all pending events results in processing of mouse events (and other GTK+ signals) also. This allows another useful feature: aborting the long running function.
When the "Cancel" button of our progress dialog is pressed it sets an internal flag. If the progress is updated next time it checks the flag. If the flag became true it throws a special exception. The throw aborts the caller of the progress update (the long running function) immediately. This exception must be catched in the signal handler of the button (or whatever called the long running function). Otherwise, it would "fall through" to the event dispatcher in Gtk::Main where it is catched definitely which would abort your application. (I saw it often enough whenever I forgot to catch.) On the other hand: catching the special exception tells clearly that the long running function has been aborted (in opposition to ended by regulary return). This may or may not be something which can be stated on GUI also.
Finally, the above solution can cause another issue: It enables to start the simulation (via GUI) while a simulation is already running. This is possible because button presses for simulation start could be processed while in progress update. To prevent this, there is actually a simple solution: set a flag at start of simulation in the GUI until it has finished and prevent further starts while the flag is set. Another option can be to make the widget/action insensitive when simulation is started. This topic becomes more complicated if you have multiple distinct long running functions in your application which may or may not exclude each other - leads to something like an exclusion matrix. Well, we solved it pragmatically... (but without the matrix).
And last but not least I want to mention that we use a similar concept for output of log views (e.g. visual logging of infos, warnings, and errors while anything long running is in progress). IMHO it is always good to provide some visual action for end users. Otherwise, they might get bored and use the telephone to complain about the (too) slow software which actually steals you the time to make it faster (a vicious cycle you have to break...)
I'm working in a software built in C++ using C++ Builder which is freezing once a month.
I'm looking in the code but it is too big to find it.
The freezes make the UI gets all white. I tried to simulate this error with some proposital bad codes (null pointers, while(1) and this kind of stuff) but never got the same blank UI.
I ran a What's Hang when it's stopped but I got nothing with it.
Someone knows what can I do in the next time to get more informations which could help me find the reason of the freezing?
A blank (white) UI generally occurs when a UI paint message is queued but not processed. Simply blocking the message queue from processing new messages is not enough if you don't do something within the UI to trigger a repaint in the first place.
As for troubleshooting the original problem - you should be looking for any code in the main thread that runs longs loop without processing new messages, or long waits on waitable objects using WaitForSingleObject() or WaitForMultipleOBjects() instead of MsgWaitForMultipleObjects(), calls to TThread::WaitFor() for threads that do not terminate in a timely manner, etc.
It is hard to troubleshoot this kind of problem without knowing what steps the user performs to lead up to the frozen UI so you know what code to start looking at.
I am currently writing a game in C++ for Windows. The server counterpart creates two additional threads at the very start. One of them handles receiving new data, and the other handles movement calculation of the objects in the game. What I managed to find out is that the last thread function (called TickFunc) is the one that slows everything down. My music freezes, I can't open new tabs in my browser, everything is slow and freezes. Even if I comment everything within the TickFunc out (leaving an empty while loop that executes forever), it still freezes, but if I do not create that thread at all, it's fine. It seems as though it slows the system down regardless of the intensity of calculation performed within the TickFunc. I would really appreciate any hints concerning what may be causing this. Thank you.
Regards,
Neob91
Put a small delay inside your infinite loop.
I made a MFC application which probably has two threads, one for receiving data from a socket using UDP protocol and one is the main thread of MFC app. While any data is received some objects, created in the main thread by new operator, would be notified to fetch the data through apply the observer design pattern. The problem is that sometimes after I clicked the close system button, the GUI of the app disappeared, but its process can still be found in the Task Manager. If I stop the data source (UDP client) this problem would never happen. Other important and maybe helpful information is listed below:
The Observer design pattern was implemented with STL container list. I have used the critical section protection in the Attach, Detach and Notify functions.
I deleted the observer objects before closing the UDP socket.
The data transfer rate may be a little faster than process data, because after closing the data source the data process is still working.
I can't figure out what lead my app can not exit completely. Please give me some clues.
This is usually caused by a thread you created and not exit it programmatically when you exit the appliation. There must be a while clause in your thread. The way to find where it is still running is:
use debug mode to start you application and click the exit button the top right corner to exit it.
Check from task manager and see if it is still running
if it is, excute Debug->Break All,
Open threads windows, double click each thread, you will find where your code is still looping.
Typically a process won't terminate because there's still a foreground thread running somewhere. You must ensure that your socket library isn't running any thread when you want to close your application.
First thing, with MFC, please use the notification based methods to get notifications on message arrivals, connections etc. So you can get rid of threads if you have.
It's quite easy to attache to a debugger and Break see which threads are existing and waiting for what.
Alternatively you can use ProcessExplorer with proper symbol configuration to see the call stacks of the threads available for the particular process.
The application can two kind of issues to exit, one could be infinite loop and other might be waiting/deadlock (e.g. socket read command is a blocking call). You can easily deduce the problem by attaching to debugger.
Otherwise please provide further information about the threads, code snippet possible.
I have an NSDocument-based Cocoa app and I have a couple of secondary threads that I need to terminate gracefully (wait for them to run through the current loop) when the users closes the document window or when the application quits. I'm using canCloseDocumentWithDelegate to send a flag to the threads when the document is closing and then when they're done, one of them calls [NSDocument close]. This seems to work peachy keen when the user closes the document window, but when you quit the app, it goes all kinds of wrong (crashes before it calls anything). What is the correct procedure for something like this?
The best possible way is for the threads to own the objects necessary for the thread to finish doing whatever it is doing to the point of being able to abort processing and terminate as quickly as possible.
Under non-GC, this means a -retain that the thread -releases when done. For GC, it is just a hard reference to the object(s) desired.
If there is some kind of lengthy processing that must go on and must complete before the document is closed, then drop a sheet with a progress bar and leave the document modal until done (both Aperture and iPhoto do exactly this).