What happens if external code throws an exception?
In VFP, there are many features to call external code, such as ActiveX controls, COM servers, DECLARE DLL or SET LIBRARY TO. In older versions, you could even LOAD and CALL machine code. If such external calls caused a crash for some reason, what should happen? In VFP5 and earlier, the exception was unhandled, and the process would crash, with the user not having much indication of why.
Try this code that will copy a string using memcpy:
DECLARE integer memcpy IN msvcrt string @ dest , string src, integer
csrc="String to copy"
cdest=SPACE(LEN(csrc))
memcpy(@cdest,csrc,LEN(csrc))
?"dest=",cdest
Now suppose the user made the call incorrectly, passing an integer of 0 as the destination. Since you don’t have the right to access memory at location 0, an Access Violation exception occurs:
DECLARE integer memcpy IN msvcrt string @ dest , string src, integer
csrc="String to copy"
cdest=SPACE(LEN(csrc))
memcpy(0,csrc,LEN(csrc))
?"dest=",cdest
VFP yields an error Declare DLL call caused an exception.
(BTW, passing an integer 0 to a DLL with a declared parameter of byref string is a feature I added back around the vfp5 timeframe. It only works with 0, because sometimes you want to pass a NULL pointer rather than an empty string)
You can also try this with a VFP COM dll: using SYS(1079) (see Intentionally crash your program)
x=CREATEOBJECT("t1.c1")
x.myeval("sys(1079)")
An error occurs: OLE IDispatch exception code 5 from t1.c1 t1.c1: .myeval d:\fox90\test\c1.prg Error in line 5 -1073741819..
And surprise surprise: convert the number to hexadecimal:
?TRANSFORM(-1073741819,"@0x")
which displays 0xC0000005
If you use early binding (not IDispatch), you get a different error:
x=CREATEOBJECTEX("t1.c1","","")
x.myeval("sys(1079)")
or
x=CREATEOBJECT("t1.c1")
y=GETINTERFACE(x,"Ic1")
y.myeval("sys(1079)")
OLE exception error: Exception code c0000005. OLE object may be corrupt
What changed so that the crash doesn’t destroy the VFP process? The call is handled by a try-except statement, which cuases the error message, rather than a crash.
When this occurs, something went wrong with the called code, and it may not have had a chance to clean up after itself. For example, the server might have opened a resource or allocated some memory, then caused the exception. That’s why the message says “may be corrupt”.
Comments
Anonymous
November 20, 2005
Calvin, very interesting. From a developer's point-of-view (who is still on VFP 8 for many technical and practical reasons), are you saying try catch can avoid the dreaded 0xc00000005 error (if you find a piece of code that produces that)? I appreciate your blog immensely, thank. DonAnonymous
November 20, 2005
I should have been more clear. The C++ try-except statement wraps calls to external code, so exceptions in external code are caught, not the VFP program that's running. Internal exceptions are caught and show the Watson dialogAnonymous
April 24, 2006
I was writing a sample about DECLARE DLL to show some of its features which I implemented about 12 years...Anonymous
July 18, 2006
is any possibilites that socket of c++ can through this exception?Anonymous
June 20, 2008
PingBack from http://jesse.finestmatingstories.com/exceptioncode.htmlAnonymous
June 14, 2009
PingBack from http://patiocushionsource.info/story.php?id=2233