0

I have to use this third party DLL that communicates with a specific hardware (Brazilian tax control related hardware).

The functions exposed in this DLL are standardized by the government and implement by hardware vendors. Our software already communicates with a couple of vendor's DLLs but with this specific vendor things are getting weird.

Well, I've isolated the problematic code as you can see bellow:

...
function ConsultarSAT(numeroSessao : Longint ) : PAnsiChar ; stdcall; external 'sat.dll';
...

procedure TForm1.Button1Click(Sender: TObject);
begin
  ConsultarSAT(GetTickCount);
  ShowMessage('Will it crash?');
end;

This code will crash if built in release config and wont if built in debug config. The ShowMessage was placed to make it clear that the crash will happen at the end of the procedure, not at the time "ConsultarSAT" is called.

By crash I mean:

Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 009E591C. Write of address 00000001'.

So I started to suspect on optimization and debugging symbols. Then I tried:

  • Debug Configuration with optimization ON: No crash
  • Release Configuration with optimization OFF: Still crash
  • Debug Configuration with all Compiler -> Debugging options OFF: No Crash
  • Release Configuration with all Compiler -> Debugging options ON: Still crash

if I run the code above, which only gets the return from the function and shows it on the showMessage, I still have the same crash scenarios but I'm able to validate that the function returned a proper value.

I guess the problem is related to some kind of mess made by the DLL in the memory, so it runs normally but when it returns and my app tries to access some memory space messed by the DLL it gets the access violation.

What else should I look for to find out what is going on here?

Ricardo Acras
  • 35,784
  • 16
  • 71
  • 112
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/176928/discussion-on-question-by-ricardo-acras-crash-only-when-using-release-build-conf). –  Jul 28 '18 at 08:41

1 Answers1

0

The problem was the way I declared the DLL function. I was using stdcall and this vendor's DLL must be called using cdecl.

The difference between these two ways to call a DLL function, according to this post, regards only to who is responsible for cleaning up the stack. When I use stdcall it is the responsibility of the function to cleanup the stack and when I use cdecl it is the responsibility of the caller.

My knowledge on this is very limited but I suppose that this behavior could explain all the weird problems I got here. The problem itself is solved and deeply tested, but it would be nice if anyone with deeper knowledge than me could go deeper in the answer so others with similar issues can waste less time than I did digging into this problem.

Ricardo Acras
  • 35,784
  • 16
  • 71
  • 112