SIGSEGV when using varargs calling

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

SIGSEGV when using varargs calling

silvioprog
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

Sven Barth-2

Am 25.01.2016 04:42 schrieb "silvioprog" <[hidden email]>:
> What I'm doing wrong? Can I use this callings on FPC in the DELPHI mode?! :-/

Neither FPC nor Delphi allow you to declare your own varargs functions. That it works in Delphi is by pure change. Trying to outsmart the compiler will only lead to trouble.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

leledumbo
Administrator
> Neither FPC nor Delphi allow you to declare your own varargs functions. That it works in Delphi is by pure change. Trying to outsmart the compiler will only lead to trouble.

AFAIR it was supported until certain FPC version, but the dropped entirely to only for external C functions.
The related error message (search for "varargs" here: http://www.freepascal.org/docs-html/user/userse62.html) explains it (better than the documentation page for varargs directive: http://www.freepascal.org/docs-html/ref/refsu88.html)
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

leledumbo
Administrator
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

Jonas Maebe-2
In reply to this post by Sven Barth-2
Sven Barth wrote:
> Am 25.01.2016 04:42 schrieb "silvioprog" <[hidden email]
> <mailto:[hidden email]>>:
>  > What I'm doing wrong? Can I use this callings on FPC in the DELPHI
> mode?! :-/
>
> Neither FPC nor Delphi allow you to declare your own varargs functions.
> That it works in Delphi is by pure change.

It will also only work on certain platforms with Delphi, or even in C.
E.g. on iOS/AArch64, varargs parameters are almost always passed
differently compared to regular parameters.


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

Jonas Maebe-2
In reply to this post by leledumbo
leledumbo wrote:
>> >  AFAIR it was supported until certain FPC version
>
> Found it:
> http://wiki.lazarus.freepascal.org/User_Changes_2.6.0#Array_of_const_parameters_and_cdecl_routines

As that entry notes, it was not supported: "There is however no way in
(Free) Pascal to access these arguments on the callee side". This
includes the case where you try to hack around this by declaring fake
parameters, such as what Silvio was doing.

The compiler didn't throw an error, but that's similar to how it didn't
throw an error in case of e.g.
http://wiki.freepascal.org/User_Changes_3.0#Classes_implementing_forward-declared_interfaces


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

silvioprog
In reply to this post by Sven Barth-2
On Mon, Jan 25, 2016 at 4:05 AM, Sven Barth <[hidden email]> wrote:

Am 25.01.2016 04:42 schrieb "silvioprog" <[hidden email]>:
> What I'm doing wrong? Can I use this callings on FPC in the DELPHI mode?! :-/

Neither FPC nor Delphi allow you to declare your own varargs functions. That it works in Delphi is by pure change. Trying to outsmart the compiler will only lead to trouble.

Indeed [1]. I found some Delphi programmers using this (wrong) calling, eg[2][3]. :-/


--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

silvioprog
In reply to this post by leledumbo
On Tue, Jan 26, 2016 at 5:34 AM, leledumbo <[hidden email]> wrote:
> Neither FPC nor Delphi allow you to declare your own varargs functions.
That it works in Delphi is by pure change. Trying to outsmart the compiler
will only lead to trouble.

AFAIR it was supported until certain FPC version, but the dropped entirely
to only for external C functions.
The related error message (search for "varargs" here:
http://www.freepascal.org/docs-html/user/userse62.html) explains it (better
than the documentation page for varargs directive:
http://www.freepascal.org/docs-html/ref/refsu88.html)

Thanks for sharing the links.

--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: SIGSEGV when using varargs calling

silvioprog
In reply to this post by leledumbo
On Tue, Jan 26, 2016 at 5:36 AM, leledumbo <[hidden email]> wrote:
> AFAIR it was supported until certain FPC version

Found it:
http://wiki.lazarus.freepascal.org/User_Changes_2.6.0#Array_of_const_parameters_and_cdecl_routines

Thanks for the link. I didn't see this Remedy: "Remove the cdecl specifier and use a Pascal-style array of const, or implement the routine in C and add external to the Pascal declaration.".

--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal