7

I'm trying to use a 3rd party object file in my 64 bit Delphi app, however it simply crashes.

Including their mod64.obj compiles and links OK and the functions in the obj can be called, but then the code crashes. The mod64.obj was assembled with MASM (v9)

I raised this with the 3rd party app developer, they downloaded the community edition of Delphi to test and this is their response:

The problem seems to be that the 64 bit linker in Delphi is not honouring the exception frames that the object module exports and imposing its own exception handler. This does not correctly handle the internally generated exceptions in our module and causes the function to crash. I've tried this building for debug and non-debug and experimented with such compiler and linker options as seemed like they might have an effect but to no avail and now I am stuck. I can see that none of our frames end up in the .pdata section of the compiled Delphi 64 bit executable.

So my question is, are there some compiler settings that are required to make this work?

David Rose
  • 130
  • 1
  • 8
  • From my own codebase, I have also suspected that this is happening, but do not have the technical know how to find out whether the exception frames are correctly declared in the combined executable. Exceptions in the external code don't always lead to crashes, but I have experienced situations where the executable terminates without any error message at all. This must be symptomatic of a catastrophic failure of the exception mechanism. I have dealt with this by working hard to stop exceptions being raised in external code. Something that can be achieved in my scenario, but not always possible. – David Heffernan Apr 23 '19 at 14:33
  • 1
    I think that the only realistic solution for you is to compile the external .obj into a DLL and link to that. I would also consider reporting this issue to QP. – David Heffernan Apr 23 '19 at 14:34
  • **Of course it is not honoring them!** Exceptions in different languages are absolutely not compatible. Exceptions should never be exported from object files to be used in **other** languages than the exact same one. I see that David already had the "pleasure" of dealing with such code. You could indeed turn it into a DLL, but be sure not to let any exception escape from the DLL. Anyway, linking to C++ objects (and exceptions are usually objects, in C++) should best be done like in my article [Using C++ objects in Delphi](http://rvelthuis.de/articles/articles-cppobjs.html). – Rudy Velthuis Apr 23 '19 at 20:38
  • Rudy - is this a 64 bit thing or 32 bit too ? I ask as the 32 bit version of the obj works fine with 32 bit delphi (and has done for many years). – David Rose Apr 23 '19 at 22:08
  • @David it's an x64 issue because of the different exception handling models. x64 exceptions are table based, in x86 they are stack based. It's clear from Rudy's comment that he doesn't really understand the issues here. – David Heffernan Apr 24 '19 at 05:59
  • @Rudy it's not about letting exceptions escape. In x86 exceptions propagate naturally up the stack because the exception model is stack based. In x64 the exception model is table based. You will want to read up on that. – David Heffernan Apr 24 '19 at 06:00
  • @Rudy for instance https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=vs-2019 and http://www.osronline.com/article.cfm%5earticle=469.htm and http://www.nynaeve.net/?p=99 – David Heffernan Apr 24 '19 at 06:11
  • In my case I needed to mask floating point exceptions when calling into external objects. Then when the call returns I check the exception flags and raise the appropriate exceptions. – David Heffernan Apr 24 '19 at 06:14
  • @David: I understand exception handling in Win32 and Win64. I guess I misunderstood the object file format. – Rudy Velthuis Apr 24 '19 at 06:29
  • @rudy I don't think you understand the low level platform details of table based exception handling, unwind info etc. given your response. You haven't had time to read those articles fully. The comment that the exception tables relating to the external object don't make it into the pdata section are very telling. – David Heffernan Apr 24 '19 at 06:54
  • @David: I do. I simply didn't understand the object format. – Rudy Velthuis Apr 24 '19 at 07:07
  • @rudy Never mind. If you can't see it now I won't keep up a pointless argument. – David Heffernan Apr 24 '19 at 07:09
  • @DavidHeffernan thanks for your input. I think this is something that definitely needs posting on QP, but I'm not sure that I understand it enough to post in a meaningful way. – David Rose Apr 24 '19 at 07:59
  • What you posted here in the question is enough I think. Especially the quote from the author of this library. The key phrase is that "none of our frames end up in the .pdata section of the compiled Delphi 64 bit executable". Include a link to this SO post. – David Heffernan Apr 24 '19 at 08:02
  • Did you submit a QP report? – David Heffernan Apr 25 '19 at 05:03
  • @DavidHeffernan - not yet. I've not done one before so need to take a look as to what it involves. – David Rose Apr 26 '19 at 10:01
  • Please let me know when you have done, or if you are struggling to do so. And if and when you do, please update the question with a link to the QP report. I know from conversations with Marco, that such cross linking is useful. – David Heffernan Apr 26 '19 at 10:55

0 Answers0