View Issue Details

IDProjectCategoryView StatusLast Update
0035233FPCCompilerpublic2019-03-16 20:14
ReporterGerrit MoellerAssigned ToJonas Maebe 
PriorityhighSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
PlatformAll (i guess)OSAll (i guess)OS VersionAll (i guess)
Product Version3.3.1Product BuildAll 
Target VersionFixed in Version3.3.1 
Summary0035233: SIGSEV crash due to corrupt call stack generated by the compiler in delphi mode
DescriptionCalling an overridden method with stdcall calling convention through an interface crashes (SIGSEV) if stdcall is not repeated in overriding method!

More Information -> See comments in submitted source code.
Steps To ReproduceCompile and run program source code submitted with this issue.
Additional Information//
// Submitted by:
//
// Gerrit Moeller
// gerrit.moeller@gm-software.de
// www.gm-software.de
//

{$MODE DELPHI} // <- Without delphi mode the parser correctly issues an error if stdcall is not repeated
               // in overriding method (see below).

program FPCIntfStdcallOverrideCrash;

type

  ISomeMethod = interface(IUnknown)
    ['{DBFB482B-76FB-4DB7-A321-1001755B1F9E}']
    function SomeMethod(const AIntArg: Integer; const AStrArg: WideString): IUnknown; stdcall;
  end;


  TBaseClassImpl = class(TInterfacedObject, ISomeMethod)
   public
    function SomeMethod(const AIntArg: Integer; const AStrArg: WideString): IUnknown; virtual; stdcall;
  end;


  TDerivedClassImpl = class(TBaseClassImpl)
  public
   //
   // In delphi mode it is not neccessary to repeat stdcall calling convention in the overriding method.
   // But the compiler then generates a call stack with another calling convention for the overriding method!
   // If you call the overriding method through an interface this crashes (SIGSEV) since it is supposed to be stdcall!
   // Repeating the calling convention in the overriding method fixes the crash.
   //
   function SomeMethod(const AIntArg: Integer; const AStrArg: WideString): IUnknown; override; // stdcall; // <- uncommenting stdcall fixes the crash
  end;


function TBaseClassImpl.SomeMethod(const AIntArg: Integer; const AStrArg: WideString): IUnknown; stdcall;
begin
  // Arguments corrupt here due to call stack mismatch!
  Result := nil; // <- SIGSEV crash here due to call stack mismatch!
end;

function TDerivedClassImpl.SomeMethod(const AIntArg: Integer; const AStrArg: WideString): IUnknown;
begin
  // Arguments corrupt here due to call stack mismatch!
 Result := inherited SomeMethod(AIntArg, AStrArg);
end;


procedure Main;
var methodIntf: ISomeMethod; unk: IUnknown;
begin
  methodIntf := TDerivedClassImpl.Create;
  unk := methodIntf.SomeMethod(100, 'Some string contents');
end;


begin
  Main;
end.

TagsNo tags attached.
Fixed in Revision41716
FPCOldBugId
FPCTarget
Attached Files

Activities

Gerrit Moeller

2019-03-15 12:40

reporter  

FPCInterfaceStdcallOverrideCrash.ppr (2,042 bytes)

Martok

2019-03-15 14:56

reporter   ~0114840

In this case, Delphi compiles TDerivedClassImpl as if there was a stdcall modifier present, which is why this works.

Jonas Maebe

2019-03-16 11:14

manager   ~0114863

FPC does the same. However, it sets that calling convention only after adding the invisible parameters (such as result), which means they were still added according to what the original calling convention required... That's indeed a pretty nasty bug.

Issue History

Date Modified Username Field Change
2019-03-15 12:40 Gerrit Moeller New Issue
2019-03-15 12:40 Gerrit Moeller File Added: FPCInterfaceStdcallOverrideCrash.ppr
2019-03-15 12:50 J. Gareth Moreton Priority normal => high
2019-03-15 12:50 J. Gareth Moreton Severity minor => crash
2019-03-15 12:50 J. Gareth Moreton Additional Information Updated View Revisions
2019-03-15 14:56 Martok Note Added: 0114840
2019-03-16 11:14 Jonas Maebe Note Added: 0114863
2019-03-16 20:14 Jonas Maebe Fixed in Revision => 41716
2019-03-16 20:14 Jonas Maebe Status new => resolved
2019-03-16 20:14 Jonas Maebe Fixed in Version => 3.3.1
2019-03-16 20:14 Jonas Maebe Resolution open => fixed
2019-03-16 20:14 Jonas Maebe Assigned To => Jonas Maebe