Reproducing MSXML Error And A Workaround
Friday, March 20th, 2009On the 14th, I promised to explain how to reproduce the errors with Visual ForPro and its buggy interaction with MSXML 3 SP10 (service pack 10).
The Problem
When the metadata property is defined in a VFP class, the property string is turned over to MSXML 3. If the string has content, MSXML returns the results to VFP, but slows down rendering the property sheets. If the string is null, MSXML throws an exception, which is ignored by VFP but not by Visual C++ if the programmer is in a debug session. Another symptom of the exception is that classes with a large amount of code (10,000 lines or more) can take significant amounts of time and processing power to save after changes are made.
I write extensions to VFP in C and C++ and I use Visual C++ 7.1 as the compiler. The resulting file is a multi-thread DLL with special tables so that VFP can call functions directly. This kind of file is called an FLL, or FoxPro Linked Library. To test the FLL’s functions, I write VFP testing code, and enter a VC debug session with VFP as the executable. I run the testing code (a form or program file) in VFP, and, if I have everything right, VC will hit the break points I have set in the C code and allow me to start tracing the execution of the function.
Except when MSXML is invoked with blank metadata. While FoxPro does not display the exception, VC in debug mode does, and sometimes thousands of times.
Reproduce The Error
- Create a VFP project in a new directory.
- Subclass a new control from a button.
- Use the MemberData Editor to create some metadata in the class.
- Create a form with a single instance of the new button class and put code into the control’s Click event to call an FLL function. You might want to include code to load the FLL in the form’s Init or Load method.
- Exit VFP with the project file still open.
- Open VC++ and create an FLL project in the test directory. Write and build the FLL.
- Remembering to set the executable to debug to VFP and setting breakpoints in your C code, enter a debug session by pressing F5.
- Keep your eye on the Output window. On my system, there are about 25 lines of output as VFP runs.
- In VFP, load the test form and click the button. The FLL function is called, and VC++ stops at the breakpoint. Press F5 to continue.
Making The Error Happen
The string in metadata is valid, and MSXML will process the string correctly. The contents of the Output Window may show the FLL being loaded, but nothing much more than that.
At this point, return to the Class Designer and delete the metadata string. Return to the Form Designer (remember VC is still in Debug mode), and run the form. When you run the form, you should see exceptions appear in the Output Window. The line(s) will contain the text “First-chance exception” and the address 0x7c812aeb. This is when the bug manifests itself!
A Workaround
The fix for this problem was so simple, it took a while for me to see it. At first, I considered replacing the MSXML 3 files with a previous version (Service Pack 9), but saw during my tests that the processing power required to save classes was the same as under SP10. The only difference between the two versions seemed to be that SP9 didn’t throw any exceptions visible in VC, even though it was having some of the same problems with blank metadata.
I finally hit on something. A control class inherits many properties and methods from its parent class, but the metadata property is not on that list when the class is newly created. It only appears when I use the MemberData Editor. The metadata property seemed to be acting like a custom property, which was added by the MemberData Editor. And, when I add custom properties, I can always remove them. I asked myself, “is the metadata property considered custom even if added by VFP?” If so, I can remove it from the class!
And that’s what I did. I visited the base class of the Form Framework (ffBaseClass) and removed the metadata property using the Edit Property/Method dialog box. And it went away, and so did the errors in VC!
That’s the workaround: remove the entire property from the class!
A Note Of Caution
This procedure is only a workaround. It may not, in fact, be a real fix, but may be opening the door for other problems in the future. But it seems to work, and Microsoft has not offered any solution to this vexing bug.