02-10-2011 07:09 AM
I found a problem involving DiscrdCtrl() and MakeMovableCtrl() functions.
Now I've been able to reproduce it in the simple example I attached: you can see it following these steps
after I found this kind of errors in my large application, they produced a FATAL error in other parts of my code.
I see this issue both with CVI 2009SP1 and CVI 2010.
Could you help me finding a way to fix this?
02-11-2011 07:38 AM
Hi Vix,
thanks for posting your demo.
I reproduced the error and I'm going to further debug the problem, also searching for possible known issues.
I'll keep you informed.
Bye,
Licia
02-17-2011 01:17 AM
Let me know when you find a solution, because it's very important for me.
Thanks in advance
02-17-2011 03:57 AM
I just happened to look into this problem as it could be of interest for some applications I am developing and found that you get the error even in a easier way:
1. Duplicate the control
2. Quit the program
and that's all!
Additionally, after quitting the program the Resource Tracking window shows up listing 10 lost memory blocks (apparently one for each control made movable)
02-17-2011 09:47 AM
Hi all,
I reported the problem to R&D for further investigation, filing a corrective action request (#285443).
I'll keep you informed in case they can find out something soon, otherwise we will have to wait for future CVI releases.
Bye,
Licia
02-17-2011 03:28 PM
Hi Vix,
Moveable controls are custom controls. Custom controls are typically customized by having custom callback functions chained onto them. (You can see how this works by looking at the code in [CVI]\toolslib\custctrl\movectrl.c). These custom control code modules use the UI library but are not part of the UI library, and the UI library has no awareness of them. Therefore, when you call UI library functions like DuplicateCtrl, it simply makes a shallow copy of the callback data that the control happens to be holding. Later on, when the UI library discards the controls, the callback chaining code intercepts this discard and tries to free the data blocks in both controls, even though there really was only one data block.
The gist of this story is that you are somewhat restricted in what you can do with custom controls. You cannot duplicate them and you cannot change their callback (unless you use ChainCtrlCallback).
You can find discussions on this topic here, here and here.
The best solution would be for you to explictly re-convert the duplicated control to a movable control after you do the copy:
IDduplicate = DuplicateCtrl (panel, MOVABLE_NUMERIC, panel, 0, VAL_KEEP_SAME_POSITION, 300);
InstallCtrlCallback (panel, IDduplicate, NULL, 0);
MakeMovableCtrl (panel, IDduplicate, "", 1, 1, 1, 1);
By the way, the leaked blocks that Roberto saw are unrelated to the control duplication. It looks as if the custom control code is not cleaning up its private data when the control is discarded. This should be fixed.
Luis
02-24-2011 09:51 AM
Hi Luis,
I followed your suggestion and this fix the issue in the example I attached to the first message of this thread.
Unfortunately, when I tried in my real project, I encountered the same error.
So I looked deeply into this issue, and I'm able to reproduce the error with a new simple example.
I think that the problem is related to MakeMovableCtrl() and InsertPanelAsTablePage(). As a matter of fact, in my real example I duplicate controls inside a tab, then I decided to discard the whole tab with DeleteTabPage() after the answer to this question.
Should I use other instructions if on the tab page there are custom controls? Or movable ones (which is the same, if I'm right)?
With this new example, as in my original one, you see the error the second time you press "Discard "Roundness factor""
Could you help me?
02-24-2011 12:21 PM
Hi Vix,
The function InsertPanelAsTabPage makes a copy of the panel, and of all the controls in it. Therefore, what I said before about DuplicateCtrl and DuplicatePanel also applies to InsertPanelAsTabPage: you must recreate the custom control after you copy it. I modified both instances in your code where you were calling InsertPanelAsTabPage:
int main (int argc, char *argv[])
{
...
DeleteTabPage (movableCtrlPanel, MOVABLE_TAB, 0, 1);
InsertPanelAsTabPage (movableCtrlPanel, MOVABLE_TAB, 0, panelTOinsert);
GetPanelHandleFromTabPage (movableCtrlPanel, MOVABLE_TAB, 0, &TabViHndl);
InstallCtrlCallback (TabViHndl, TOINS_NUMERIC, NULL, 0);
MakeMovableCtrl (TabViHndl, TOINS_NUMERIC, "", 1, 1, 1, 0);
SetMovableCtrlAttribute (TabViHndl, TOINS_NUMERIC, MOVECTRL_ATTR_CTRL_MOVABLE, 1);
SetCtrlAttribute (movableCtrlPanel, MOVABLE_TAB, ATTR_CTRL_INDEX, 0);
...
}
int CVICALLBACK Discard (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int TabViHndl;
switch (event)
{
case EVENT_COMMIT:
DeleteTabPage (movableCtrlPanel, MOVABLE_TAB, 0, 1);
SetCtrlAttribute (panel, MOVABLE_DUPL, ATTR_DIMMED, 0);
SetCtrlAttribute (panel, MOVABLE_DISC, ATTR_DIMMED, 1);
InsertPanelAsTabPage (movableCtrlPanel, MOVABLE_TAB, 0, panelTOinsert);
GetPanelHandleFromTabPage (movableCtrlPanel, MOVABLE_TAB, 0, &TabViHndl);
InstallCtrlCallback (TabViHndl, TOINS_NUMERIC, NULL, 0);
MakeMovableCtrl (TabViHndl, TOINS_NUMERIC, "", 1, 1, 1, 0);
SetCtrlAttribute (panel, MOVABLE_TAB, ATTR_CTRL_INDEX, 0);
break;
}
return 0;
}
09-13-2012 05:35 AM
CAR #285443 has been fixed in CVI 2012