03-24-2010 03:22 PM
I'm getting a 'general protection fault' in the CVI RTE (ver 9.0.1.375) and I'm a little stumped on how to debug it. When run in debug mode the fatal error stops on a 'ProcessSystemEvents();' call. The memory location the GPF is pointing to is in CVIRTE.dll.
I know there is a new runtime engine, but as multiple users use the PC this affects I'm apprehensive to just try the latest RTE to see if it resolves the issue. I'm hoping I can get a definitive answer so it will make it easier on my end to push this change (if this will in fact solve the issue).
I have uploaded the DrWatson dump of the crash to ftp://ftp.ni.com/incoming/MarkAliasUser.dmp
Unfortunately I can't send a snippet of the code, but if you can even point in an avenue I can look at on my end, it would be appreciated
Mark
03-25-2010 12:09 PM
Hey Mark -
I took a look at the crash dump this morning, and although it looked familiar to me, I can't say definitively that it is a known issue that was fixed in the LabWindows/CVI 2009 RTE. A couple things could help narrow this down:
Let me know when you've placed a couple more dumps up on the ftp site, and I'll take a look. Based on what I see, I'll let you know how best we should procede.
Thanks, and sorry for any inconvenience -
NickB
National Instruments
03-25-2010 12:39 PM
Thanks Nick. The program is simplistic in nature and complicated in execution (yay legacy!). There a fair number of what I would consider 'bad practices' in this code, but I'm not allowed to touch anything unless it's a proven issue.
The serial comms is a serial link to a device under test. The GUI is just a pop-up they use to confirm with the operator the device appears similiar to a picture in the GUI. (a "Did the device look like this?" type thing). Then we spin (loop,while) on a 'ProcessSystemEvents' as a button push on the UIR will set a flag to kick out of that loop and close the UIR.
The crash occurs on that 'ProcessSystemEvents' routinuely. Not every time, but the longer you sit in that while loop, the more likely to get a crash.
My apologies for not sending the full dump. I've uploaded a full dump to the ftp site ftp://ftp.ni.com/incoming/MarkAliasFullUser.dmp
If there is anything other information you need, please don't hesitate to ask.
Thanks,
Mark
03-26-2010 04:48 AM - edited 03-26-2010 04:49 AM
MarksAlias wrote:
...I know there is a new runtime engine, but as multiple users use the PC...
If you build the application and set the distribution kit to install the CVI runtime files in the application directory, rather than the system one, you should be able to update your own private copy of the runtime engine without affecting other users.
JR
03-26-2010 05:36 PM
Mark -
Sorry to take so long to get back to you, things got really busy here today...
While I'm still not entirely sure about why the crash is happening, I think I can give you some pointers about what to look at in your code. There's certainly a problem on our end that we will look to fix, but there may be a chance you can work around it.
It looks like the immediate cause of the crash may be some form of stack corruption. Essentially, we are getting into an infinite recursion that eventually hoses some of our global data structures. The cause of this is as follows:
Without being able to see your code, all I can say is that it's often unnecessary to call ProcessSystemEvents from within a callback function, and this can often lead to problems.
Hopefully this is enough information to help you track something down. If there is any way we could get this program, or a smaller one, to reproduce the issue, we could get a much better handle on what's happening, but for the moment, it does not look like this is an issue that would be solved by an upgrade of your CVI RTE.
NickB
National Instruments
03-29-2010 09:18 AM
Thanks for the info Nick. I think I've got a solution but I wanted to run it by you for a sanity check if you don't mind. The big difference is kicking off the new panel as a child rather than a top-level, and the use of runUserInterface and quitUserInterface. The basic point is we need to load a new panel (bezelGUI.uir) to get some information from an operator, then return to the main panel to collect and process that info. The below does work in that it removes the 'ProcessSystemEvents' loop that was causing the recursion error, but wanted to make sure there was something else i was missing that would come back to bite me.
Old code:
bezelPanelHandle = LoadPanel(0 ".\\bezelGUI.uir", BEZELGUI);
... set some attribues on bezelPanelHandle ...
DisplayPanel(bezelPanelHandle);
do {
// Do nothing, wait for Done key to be pressed
ProcessSystemEvents();
} while(gDoneBezelKey == FALSE);
HidePanel(bezelPanelHandle);
Note: In bezelPanelHandle, there's a button that, when pressed sets gDoneBezelKey to TRUE
New Code:
bezelPanelHandle = LoadPanel(parentPanelHandle ".\\bezelGUI.uir", BEZELGUI);
... set some attribues on bezelPanelHandle ...
DisplayPanel(bezelPanelHandle);
RunUserInterface ();
HidePanel(bezelPanelHandle);
Note: Now in bezelPanelHandle the button just executes QuitUserInterface.
03-29-2010 12:13 PM
Hey Mark -
I think you are correct that the biggest difference is that you are now loading the second panel as a child instead of a top level panel. This means that there is now only one HWND that can receive messages internally, which is likely part of the root of the issue. Whether you use ProcessSystemEvents or RunUserInterface almost certainly makes no difference.
I would like to run one thing past you again, because I think I did not say it quite clearly enough last time. The stack trace in the dump indicates that in one of your panel callbacks (likely the original parent, but I can't be sure), you are calling ProcessSystemEvents when handling the EVENT_MOUSE_POINTER_MOVE event (or perhaps in a default event case or something similar). Is this the case? If so, is this necessary? If you would like to restore the original behavior of a top level panel, this is one area I would take another look at.
NickB
National Instruments
03-29-2010 01:54 PM
I'm not sure this is the case - but maybe I'm not understanding you properly. You're saying you're seeing a ProcessSystemEvents while in the callback? Below is the code for the only callback of the child panel and there is no direct ProcessSystemEvents. The gDoneBezelKey is the global that was being used to signal to the main panel to continue..
int CVICALLBACK DoneBezelKeyTest(int panel, int control, int event, void *callbackData, int eventData1, int eventData2) {
switch(event) {
case EVENT_COMMIT:
GetCtrlVal(bezelPanelHandle, BEZELGUI_OPERATOR_RESPONSE1, &gBezelResponse[0]);
GetCtrlVal(bezelPanelHandle, BEZELGUI_OPERATOR_RESPONSE2, &gBezelResponse[1]);
GetCtrlVal(bezelPanelHandle, BEZELGUI_OPERATOR_RESPONSE3, &gBezelResponse[2]);
GetCtrlVal(bezelPanelHandle, BEZELGUI_OPERATOR_RESPONSE4, &gBezelResponse[3]);
gDoneBezelKey = TRUE;
break;
}
return 0;
}
Does that line up with what you're seeing? The mainpanel is from a function panel (and used on many other project), but I can dig into that and see if there are any processsystemevents in the callback fo that as well - though the crash I'm seeing is unique to this project (as far as i can tell)
Again, thanks for your help Nick!
03-29-2010 06:43 PM
Hey Mark,
Acutally, what the crash seems to be indicating is that one of the calls to ProcessSystemEvents in your do loop results in the event EVENT_MOUSE_POINTER_MOVE (value 33) being sent to one of your panel callbacks - not the button callback, and ProcessSystemEvents being called from that panel callback. Something like the following...
Do you have anything that looks anything like this in your code?
NickB
National Instruments
03-30-2010 07:32 AM
Nick,
I couldn't find anything for a direct result of a mouse event. I could only find one instance of a callback attached to a panel (the rest are attached to timers and command buttons). Could this be the offending callback?
int CVICALLBACK MainPanelCallback(int panel, int event, void *callbackData, int eventData1, int eventData2)
/* shut off hardware, exit program (from close box) */
{
if (event == EVENT_CLOSE) {
SuspendTimerCallbacks ();
g_tests_active = FALSE;
Close(); // and EXIT
}
ProcessSystemEvents();
return(0);
}
It seems to describe what you were seeing, but this callback is tied to the main panel, not the child panel where we see the crashes. I'm also a little confused as to why I'm only seeing this crash for this particular panel as it appears we kick off several panels in this manner (as a stand-alone rather than a child) but I'm unable to get the same crash.
For now I'm going to continue with just setting the panel as a child, as that seems to at least stop this crash. Of course my worry is there's another one lurking nearby for a similiar reason so if you do have any thoughts on the matter I'd appreciate them.
Regardless of the outcome though, I NEVER would have been able to nail this one down without your help - thank you!
Mark