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 (6)

  1. don dodge says:

    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. Don

  2. Calvin_Hsia says:

    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 dialog

  3. I was writing a sample about DECLARE DLL to show some of its features which I implemented about 12 years…

  4. ashok basutkar says:

    is any possibilites that socket of c++ can through  this exception?