Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-06

Stack alignmennt in call from C++ to FPC

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Josue Andrade Gomes

Stack alignmennt in call from C++ to FPC

Hi,

I have recently ported a Delphi application to Lazarus/FPC (Win32/x86). This application makes use of a DLL implemented in MS Visual C++ 2010.

The calls from FPC code to C++ code work fine. However this DLL also has a callback
system for notifications. When the DLL calls a FPC callback function a crash occurs inside the DLL with a 'Datatype misalignment' exception (1).

Some references (eg (2)) claim that MSVC aligns the stack at 4-byte boundaries while GCC aligns
at 16-byte boundaries. I have found no confirmation on those claims.

With GCC I could use __attribute__((force_align_arg_pointer)) in the callback declaration.
Or even -mstackrealign. However I can't find a similar option with FPC.

Any idea?

Thanks for any help.

Here some code excerpts:

{ FPC }
type
 TMyCallback = procedure(s : PChar); stdcall;
...
procedure RegisterCallBack(callback: TMyCallback); stdcall; external
'MyDll.dll';
...
procedure Callback(s : PChar); stdcall;
begin
{ use s }
end;
...
RegisterCallBack(Callback);
...
// C++
typedef void (__stdcall *Callback_t)(const char* s);
extern "C" {
__declspec(dllexport) void RegisterCallback(Callback_t p);
}

...

static Callback_t callback = 0;

void RegisterCallback(Callback_t p)
{
callback(p);
}
...
// at some point the callback is called;
if (callback)
callback("hello world"); // <== crashes here

Josue A. Gomes josuegomes.com (1) Actual error: Unhandled exception at 0x00411990 in Project1.exe: 0x80000002: Datatype misalignment. (2) http://www.gamedev.net/topic/482230-mingw-dll-used-in-mingw-and-vc-app-memory-alignment/
Jonas Maebe
to Josue Andrade Gomes
Josue Andrade Gomes wrote
Some references (eg (2)) claim that MSVC aligns the stack at 4-byte boundaries while GCC aligns at 16-byte boundaries. I have found no confirmation on those claims.

Stack alignment is not a compiler property, but a platform property. The stack alignment on Win32 is 4 bytes. On Linux/i386 it used to 4 bytes, but there has been an unofficial switch to 16 bytes (which, in all fairness, was pushed by gcc for SSE/performance reasons).

I don't immediately see what the problem is in your case. Usually it's a mismatch of calling conventions, but that seems to be fine in the code you posted.

Jonas

Josue Andrade Gomes
to Jonas Maebe
Jonas Maebe wrote 11 lines
On 05 Jun 2013, at 15:04, Josue Andrade Gomes wrote: > Some references (eg (2)) claim that MSVC aligns the stack at 4-byte > boundaries while GCC aligns > at 16-byte boundaries. I have found no confirmation on those claims. Stack alignment is not a compiler property, but a platform property. The stack alignment on Win32 is 4 bytes. On Linux/i386 it used to 4 bytes, but there has been an unofficial switch to 16 bytes (which, in all fairness, was pushed by gcc for SSE/performance reasons). I don't immediately see what the problem is in your case. Usually it's a mismatch of calling conventions, but that seems to be fine in the code you posted.

Thanks for your answer. Anyway the problem seems to be something else. I have written a small test but could not reproduce the problem. I'll continue investigation.

If someone is interested my small test can be found at www.josuegomes.com/fp-msvc.zip
It contains a DLL built with MSVC and two Pascal applications that load the DLL, pass the callback function
and call it.

Thanks again for your help. If I find something of interest I'll post it here.

regards,
josue

Josue Andrade Gomes
to Josue Andrade Gomes

On Thu, Jun 6, 2013 at 11:09 AM, Josue Andrade Gomes wrote:

I reproduced the problem with a small Lazarus application. The crash occurs inside fpc_popaddrstack.

0x40b750 <fpc_popaddrstack+48> jmp 0x40b759 <fpc_popaddrstack+5 0x40b752 <fpc_popaddrstack+50> mov (%ebx),%eax

0x40b754 <fpc_popaddrstack+52> mov 0x4(%eax),%eax

0x40b757 <fpc_popaddrstack+55> mov %eax,(%ebx) 0x40b759 <fpc_popaddrstack+57> mov (%esp),%ebx 0x40b75c <fpc_popaddrstack+60> add $0x4,%esp 0x40b75f <fpc_popaddrstack+63> ret

I also found this http://comments.gmane.org/gmane.comp.ide.lazarus.general/68243

Could be related? Any ideas?

Sourcecode for my tests can be found at: www.josuegomes.com/fp-msvc.zip

regards,
josue

Josue Andrade Gomes
to Josue Andrade Gomes

Initializing the thread system with a dummy thread as suggested by http://wiki.freepascal.org/Multithreaded_Application_Tutorial has (apparently) fixed the problem.

Thanks all for the support.

Josue Andrade Gomes On Fri, Jun 7, 2013 at 10:03 AM, Josue Andrade Gomes wrote: > On Thu, Jun 6, 2013 at 11:09 AM, Josue Andrade Gomes > wrote: > > I reproduced the problem with a small Lazarus application. The crash > occurs inside fpc_popaddrstack. > > 0x40b750 <fpc_popaddrstack+48> jmp 0x40b759 <fpc_popaddrstack+5 > 0x40b752 <fpc_popaddrstack+50> mov (%ebx),%eax >> 0x40b754 <fpc_popaddrstack+52> mov 0x4(%eax),%eax > 0x40b757 <fpc_popaddrstack+55> mov %eax,(%ebx) > 0x40b759 <fpc_popaddrstack+57> mov (%esp),%ebx > 0x40b75c <fpc_popaddrstack+60> add $0x4,%esp > 0x40b75f <fpc_popaddrstack+63> ret > > I also found this http://comments.gmane.org/gmane.comp.ide.lazarus.general/68243 > > Could be related? Any ideas? > > Sourcecode for my tests can be found at: www.josuegomes.com/fp-msvc.zip > > regards, > josue