[fpc-pascal] SIGSEGV when using varargs calling

silvioprog silvioprog at gmail.com
Mon Jan 25 04:41:04 CET 2016


Hello,

Consider the following types:

  TPuts1 = procedure; cdecl varargs;
  TPuts2 = procedure(par: string); cdecl varargs;
  TPuts3 = procedure(const par: string); cdecl varargs;

this procedure:

  procedure Puts(par1, par2, par3: string); cdecl;
  begin
    Write(par1, ' ');
    Write(par2, ' ');
    Write(par3, ' ');
    Writeln('');
  end;

and this callings:

var
  PutsX: Pointer;
begin
  TPuts1(@Puts)('Hello1', 'World1', 'HogeMoge1');
  TPuts2(@Puts)('Hello2', 'World2', 'HogeMoge2');
  TPuts3(@Puts)('Hello3', 'World3', 'HogeMoge3');
  PutsX := @Puts;
  TPuts1(PutsX)('Hello4', 'World4', 'HogeMoge4');
  TPuts2(PutsX)('Hello5', 'World5', 'HogeMoge5');
  TPuts2(PutsX)('Hello6', 'World6', 'HogeMoge6');
  Readln;
end.

It compiles fine on Delphi, but in FPC I got the following error:

'Wrong number of parameters specified for call to "<Procedure Variable>"'.

OK, I just commented the wrong lines to be able to compile that:

begin
//  TPuts1(@Puts)('Hello1', 'World1', 'HogeMoge1');
  TPuts2(@Puts)('Hello2', 'World2', 'HogeMoge2');
  TPuts3(@Puts)('Hello3', 'World3', 'HogeMoge3');
  PutsX := @Puts;
//  TPuts1(PutsX)('Hello4', 'World4', 'HogeMoge4');
  TPuts2(PutsX)('Hello5', 'World5', 'HogeMoge5');
  TPuts2(PutsX)('Hello6', 'World6', 'HogeMoge6');
  Readln;
end.

But, after compile it in FPC and run the program, I got a SIGSEGV with the
following stack trace (compiled on Delphi it runs properly):

#0 SYSTEM_$$_SPTR$$POINTER at :0
#1 fpc_ansistr_incr_ref at :0
#2 PUTS(<error reading variable>, <error reading variable>, <error reading
variable>) at project1.lpr:14
#3 main at project1.lpr:25

However, if you declare it using integers, it compiles and works fine in
both compilers:

  TPuts = procedure(p0: Integer); cdecl varargs;

  procedure Puts(p1, p2, p3: Integer); cdecl;
  begin
    WriteLn(p1, p2, p3);
  end;

begin
  TPuts(@Puts)(1, 2, 3);

Below the generated asm to check why the first calling doesn't work in FPC
if the params was declared as strings:

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}

  TPuts = procedure(const p0: string); cdecl varargs;

  procedure Puts(const p1, p2, p3: string); cdecl;
  begin
    WriteLn(p1, p2, p3);
  end;

begin
  TPuts(@Puts)('1', '2', '3');

[FPC]

project1.lpr:17  TPuts(@Puts)('1', '2', '3');
004015B9 6a33                     push   $0x33
004015BB 6a32                     push   $0x32
004015BD b810b04000               mov    $0x40b010,%eax
004015C2 50                       push   %eax
004015C3 b850154000               mov    $0x401550,%eax
004015C8 ffd0                     call   *%eax
004015CA 83c40c                   add    $0xc,%esp

[/FPC]

[DELPHI]

Project1.dpr.17: TPuts(@Puts)('1', '2', '3');
004060D4 6A33             push $33
004060D6 6A32             push $32
004060D8 6808614000       push $00406108
004060DD B86C5B4000       mov eax,$00405b6c
004060E2 FFD0             call eax
004060E4 83C40C           add esp,$0c

[/DELPHI]

What I'm doing wrong? Can I use this callings on FPC in the DELPHI mode?!
:-/

-- 
Silvio Clécio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20160125/8afa78d7/attachment.html>


More information about the fpc-pascal mailing list