Link to home
Start Free TrialLog in
Avatar of jason211
jason211Flag for Afghanistan

asked on

Is Delphi/VB6 no longer COM compatible with .Net 4.0

How do you handle the conflicting FPU settings between Delphi($1372) and .Net runtime(0x027F)?  The .net 4 runtime will throw a stack overflow triggered by a delphi application after the runtime is loaded into the delphi process.  (i.e. start delphi app, load .net dll, then in delphi app divide by zero a couple times in a row).

  Prior to .net 4, the suggested fix was to toggle the FPU to $133F before the .net call then restore it afterward, this does not appear to work in .net 4.  Note: this worked prior to .net 4.


procedure TForm1.Button1Click(Sender: TObject);
const
  DOTNETDLL = 'dnetTestDivideByZero';
  DOTNETCOMTYPE = 'dnetTestDivideByZero.dnetTestDivideByZeroInterface';
var
  ADotNetObject: Variant;
  CW: Word;
  a, b: Double;
begin
  CW:= Get8087CW;

  // Disable FPU exceptions
  Set8087CW( $133f );
  try
    try
      ADotNetObject:= CreateOleObject( DOTNETCOMTYPE );
    except on E: Exception do
      begin
        ShowMessage( 'Please register this dll by calling C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe dnetTestDivideByZero.dll.'+
        '  This will register the dll for COM.  You will notice that if you compile the vinlib.dll for .net 2.0 or 3.5 and regasm the dll, that the problem does not occur.' );
        Exit;
      end;
    end;

    try
      ADotNetObject.DummyMethodThatDoesNothing;
    finally
      varClear( ADotNetObject );
    end;

  finally
    Set8087CW( CW );
  end;


  try
    b := 0;
    a := 1 / b;   // wont throw
    a := 1 / b;   // will throw...this is b/c of FPU design
  except
    on E: Exception do
      // never get here
      ShowMessage('This should be Divide by zero error. However, it goes uncaught b/c of stack overflow error when using .net 4.0.  Failed with Error = '+  E.Message );
  end;

 ShowMessage('Success')
end;

Open in new window

Avatar of aikimark
aikimark
Flag of United States of America image

My gut feeling is that the problem is on the .Net COM side of this system.
I have seen evidence, through my own research, that there are many people experiencing issues with the interop on .net 4.

http://social.msdn.microsoft.com/Forums/en-US/vbinterop/thread/a5cfc084-ef34-42fe-9e65-edfd606a4600/
http://social.msdn.microsoft.com/Forums/en-US/vbinterop/thread/b59de045-02aa-4e5b-8d6c-7af379325c81/

(just to show a couple)

It is natural that these type of examples (.NET using COM) would be more prevalent than examples of unmanaged code calling .NET.  The key point here is that there IS an issue with the interop which is used in both cases.  As aikimark mentioned, the problem appears to be on the MS side.

I hope that the examples I gave will help to guide you in your search for answers (looking into .NET 4 interop issues).  Sometimes, knowing where to look is the biggest part of the battle.
Avatar of jason211

ASKER

Aikimark,
  The title should include "any compile which modifies the FPU control word exception masks(in this case the overflow and divide by zero masks)", but that seems like a mouth full.  :)  
  I've continued working at this and have added a stack trace below to the issue.  What appears to be the issue to me is that the .net 4.0 clr has hooked into the Vector Exception Handler and is catching FPU exceptions that don't originate from it. (i.e. the .net COM Server did not throw these....the Delphi COM client did).  Anyone who can help on how to disable or handle these handlers that didn't appear to be in .net 2.0 clr will get the points, please please please help.

DevelopmentGuru,
  Thank you, but these links are a little different and don't provide any information as to a likely solution.  Their test cases is not clear either, as to what is happening.


ntdll.dll!strncpy()  + 0x2cf bytes	
 	[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]	
 	ntdll.dll!RtlCaptureContext()  + 0x187 bytes	
 	ntdll.dll!RtlDosSearchPath_Ustr()  + 0x994 bytes	
 	ntdll.dll!KiUserExceptionDispatcher()  + 0xf bytes	
 	clr.dll!CLRVectoredExceptionHandlerShim()  + 0xa3 bytes	
 	ntdll.dll!strncpy()  + 0x2cf bytes	
 	ntdll.dll!RtlCaptureContext()  + 0x187 bytes	
 	ntdll.dll!RtlDosSearchPath_Ustr()  + 0x994 bytes	
 	ntdll.dll!KiUserExceptionDispatcher()  + 0xf bytes	
 	clr.dll!CLRVectoredExceptionHandlerShim()  + 0xa3 bytes	
 	ntdll.dll!strncpy()  + 0x2cf bytes	
 	ntdll.dll!RtlCaptureContext()  + 0x187 bytes	
 	ntdll.dll!RtlDosSearchPath_Ustr()  + 0x994 bytes	
 	ntdll.dll!KiUserExceptionDispatcher()  + 0xf bytes

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of aikimark
aikimark
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
There are times, even though we experts hate to say it, when there is no viable solution.  Everything points to this being a problem that MS has yet to address.  The danger in attempting to address it on your own should be obvious.  If you were to correct it (by using the lowest level of debugging to find a way to balance and offset the flaw in the MS code) then the next release would break your code making you look bad.  Worse than looking bad... a fix at this level, once broken, may result in SEVERE system crashes.

I would attribute this to the normal type of issues you run into when you attempt to "ride the bleeding edge".
aikimark:
  definitely bad news right now...hope they get that fix in .net 4.5 or a 4.0

developmentguru:
  i agree, whether riding it or being forced into riding it when using multiple tools/utilities/components on competing versions....where's the band-aides?
While this wasn't a solution to the problem, it provided the link to the bug report causing the problem.  thank you aikimark