Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On Thu, 2 Oct 2014, Reinier Olislagers wrote: On 02/10/2014 12:19, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: On 30/09/2014 22:05, Mark Morgan Lloyd wrote: Marco van de Voort wrote: In our previous episode, Sven Barth said: It is indeed true that all units are initialized once the main code Reinier: did you get as far as looking in Dynlibs for an error message immediately after trying to connect to the database? No, I didn't. Assuming you've got >= 2.6.2, modify your code to look like this: Sorry to be a bit abrupt here but I'm not really interested in tweaking this either. I've submitted a bug report which was closed. If anybody else wants to look into this, fine by me, but I won't spend any more time on it. Some background: if I'm using e.g. FPC-provided units that just happen to load dlls dynamically (such as sqldb but probably also others) I, as a programmer, do not necessarily know or want to know that implementation detail. Rather than messing with havint to adapt code for those scenarios I'll just not use the initalization sections at all as I documented on the wiki. That is my conclusion since ages: I don't use initialization sections, except maybe to initialize a variable. You quickly learn this when you need to debug e.g. windows services. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 02/10/2014 12:19, Mark Morgan Lloyd wrote: > Reinier Olislagers wrote: >> On 30/09/2014 22:05, Mark Morgan Lloyd wrote: >>> Marco van de Voort wrote: In our previous episode, Sven Barth said: > It is indeed true that all units are initialized once the main code >>> Reinier: did you get as far as looking in Dynlibs for an error message >>> immediately after trying to connect to the database? >> >> No, I didn't. > > Assuming you've got >= 2.6.2, modify your code to look like this: Sorry to be a bit abrupt here but I'm not really interested in tweaking this either. I've submitted a bug report which was closed. If anybody else wants to look into this, fine by me, but I won't spend any more time on it. Some background: if I'm using e.g. FPC-provided units that just happen to load dlls dynamically (such as sqldb but probably also others) I, as a programmer, do not necessarily know or want to know that implementation detail. Rather than messing with havint to adapt code for those scenarios I'll just not use the initalization sections at all as I documented on the wiki. Thanks for all the help. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Reinier Olislagers wrote: On 30/09/2014 22:05, Mark Morgan Lloyd wrote: Marco van de Voort wrote: In our previous episode, Sven Barth said: It is indeed true that all units are initialized once the main code Reinier: did you get as far as looking in Dynlibs for an error message immediately after trying to connect to the database? No, I didn't. Assuming you've got >= 2.6.2, modify your code to look like this: uses DynLibs; .. WriteLn('Before TDBInterface.Create(): ', GetLoadErrorStr); DBLayer:=TDBInterface.Create; WriteLn('After TDBInterface.Create(): ', GetLoadErrorStr); On Linux, I can see it calling the database connection stuff but then it raises an exception because it can't find the named server etc. So at least on Linux it's apparently transferring control into the demand-loaded database stuff, since otherwise there wouldn't be the messages as shown below. Whether it's appropriate and portable to do it like that is a different issue. I don't want to have to spend time changing your test code to suit PostgreSQL or digging out names etc. for the limited number of Firebird databases I've got set up, and I /really/ don't want to start fiddling with Windows. Before TDBInterface.Create(): An unhandled exception occurred at $B767EFEF : EIBDatabaseError : : DoInternalConnect : -Unable to complete network request to host "firebirdserver". -Failed to locate host machine. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
In our previous episode, Sven Barth said: > > So the obvious question might be if the unit initialization really belongs > > into the library initialization like that. > > The only other alternative would be to add the RTL initialization code > to each exported function. I don't consider this a viable alternative. Simpler, for manual managed DLLs, you need to manually call an initialization and finalization. Period. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 30/09/2014 22:05, Mark Morgan Lloyd wrote: > Marco van de Voort wrote: >> In our previous episode, Sven Barth said: >>> It is indeed true that all units are initialized once the main code > Reinier: did you get as far as looking in Dynlibs for an error message > immediately after trying to connect to the database? No, I didn't. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Am 30.09.2014 22:19 schrieb "Mark Morgan Lloyd" < markmll.fpc-pas...@telemetry.co.uk>: > > Sven Barth wrote: > >> The only other alternative would be to add the RTL initialization code to each exported function. I don't consider this a viable alternative. > > > Which is more or less what Reinier's working code did. I'd hate that to be an implicit default. > > >> Note: Dynamic packages won't have this problem, because: >> - for packages linked at compile time the initialization is run as part of the program initialization AFTER the OS has initialized the library (which doesn't do much in case of a package) >> - for packages loaded at runtime it's done as part of the LoadPackage call >> That's however only possible, because dynamic packages are very different from simple libraries (and stuffed with compiler magic). > > > Is it possible for code in a unit to determine what sort of project it's part of, i.e. a standalone program, a library etc.? Could the RTL have a flag indicating that initialisation (or finalisation?) blocks were currently being run, and anything called should assume that facilities were restricted? Isn't there a IsLibrary variable in System? For sure there is a IsPackage variable which will be true if the unit is part of a package (though I still need to find out how to implement this). You don't need a flag for initialization/finalization blocks, because if your code resides in one then you are obviously run inside one... Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Sven Barth wrote: The only other alternative would be to add the RTL initialization code to each exported function. I don't consider this a viable alternative. Which is more or less what Reinier's working code did. I'd hate that to be an implicit default. Note: Dynamic packages won't have this problem, because: - for packages linked at compile time the initialization is run as part of the program initialization AFTER the OS has initialized the library (which doesn't do much in case of a package) - for packages loaded at runtime it's done as part of the LoadPackage call That's however only possible, because dynamic packages are very different from simple libraries (and stuffed with compiler magic). Is it possible for code in a unit to determine what sort of project it's part of, i.e. a standalone program, a library etc.? Could the RTL have a flag indicating that initialisation (or finalisation?) blocks were currently being run, and anything called should assume that facilities were restricted? -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Marco van de Voort wrote: In our previous episode, Sven Barth said: It is indeed true that all units are initialized once the main code block of the library is called, but you are still inside the library initialization initiated by the OS and thus you are subject to its restrictions which in the case of Windows includes not to load any libraries there. So the obvious question might be if the unit initialization really belongs into the library initialization like that. Assuming that e.g. connecting to a database uses the Dynlibs unit, is there any way that this could recognise that it was being invoked from DLL/so initialisation code and raise a "don't try that here" exception? Reinier: did you get as far as looking in Dynlibs for an error message immediately after trying to connect to the database? -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 30.09.2014 20:17, Marco van de Voort wrote: In our previous episode, Sven Barth said: It is indeed true that all units are initialized once the main code block of the library is called, but you are still inside the library initialization initiated by the OS and thus you are subject to its restrictions which in the case of Windows includes not to load any libraries there. So the obvious question might be if the unit initialization really belongs into the library initialization like that. The only other alternative would be to add the RTL initialization code to each exported function. I don't consider this a viable alternative. Note: Dynamic packages won't have this problem, because: - for packages linked at compile time the initialization is run as part of the program initialization AFTER the OS has initialized the library (which doesn't do much in case of a package) - for packages loaded at runtime it's done as part of the LoadPackage call That's however only possible, because dynamic packages are very different from simple libraries (and stuffed with compiler magic). Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
In our previous episode, Sven Barth said: > It is indeed true that all units are initialized once the main code block > of the library is called, but you are still inside the library > initialization initiated by the OS and thus you are subject to its > restrictions which in the case of Windows includes not to load any > libraries there. So the obvious question might be if the unit initialization really belongs into the library initialization like that. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Am 30.09.2014 15:07 schrieb "Mark Morgan Lloyd" < markmll.fpc-pas...@telemetry.co.uk>: >> As far as I know, the initialization entry point is called automatically. >> But the compiler experts should confirm this. IIRC the behaviour changed as the support for libraries improved; > > > ..(pending comment from compiler experts) there are completely separate trees of units in the main program and each dynamically-loaded library. The OS calls the initialisation block(s) for each library, and then finally calls the initialisation block for the main program. So in the context of one particular library, code in the main library initialisation block should have a similar standing to that in the main program initialisation block: everything else in that context (i.e. in the library or in the main program) has been initialised before it is called, and when it exits it goes back to the OS (possibly via finalisation blocks). It is indeed true that all units are initialized once the main code block of the library is called, but you are still inside the library initialization initiated by the OS and thus you are subject to its restrictions which in the case of Windows includes not to load any libraries there. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Michael Van Canneyt wrote: However I'd precede that by a thought based on what Jose said. In your example, you're opening the database in the initialisation block of businesslayer.pas, which is invoked at an arbitrary position in the init sequence of the DLL/so. If that operation were moved instead to the initialisation block of testdbdll.lpr, which in the context of the DLL/so is analogous to a program's main block, it might work. No. this is not correct. For a library, this is analogous to initialization code of a unit, it's just the 'last' unit being initialized. Does the main program explicitly call the initialisation entry point of the (dynamically-loaded) library, or it this done by the OS? I was under the impression that the two were basically asynchronous and (as a particular example) both the program and the library would have distinct copies of the system unit with their own global variables etc. hence the memory manager problem. The memory manager problem is completely unrelated to this. DLL and calling program simply have different copies of the FPC memory manager. That is what needs to be solved with dynamic packages. Yes, agreed. Except that if cmem (or whatever) isn't being used there are two completely separate copies of the memory manager because... As far as I know, the initialization entry point is called automatically. But the compiler experts should confirm this. IIRC the behaviour changed as the support for libraries improved; ..(pending comment from compiler experts) there are completely separate trees of units in the main program and each dynamically-loaded library. The OS calls the initialisation block(s) for each library, and then finally calls the initialisation block for the main program. So in the context of one particular library, code in the main library initialisation block should have a similar standing to that in the main program initialisation block: everything else in that context (i.e. in the library or in the main program) has been initialised before it is called, and when it exits it goes back to the OS (possibly via finalisation blocks). -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On Tue, 30 Sep 2014, Mark Morgan Lloyd wrote: Michael Van Canneyt wrote: On Tue, 30 Sep 2014, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: On 29/09/2014 19:30, Reinier Olislagers wrote: Re bug report: agreed. I'll raise it. Jonas has already closed it, noting "http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx "*** The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. *** "I.e., what you are doing is unsupported ("must not call the LoadLibrary or LoadLibraryEx function"). I think that on most unix platforms, trying to load libraries from other the init function of other libraries is not supported either." However I'd precede that by a thought based on what Jose said. In your example, you're opening the database in the initialisation block of businesslayer.pas, which is invoked at an arbitrary position in the init sequence of the DLL/so. If that operation were moved instead to the initialisation block of testdbdll.lpr, which in the context of the DLL/so is analogous to a program's main block, it might work. No. this is not correct. For a library, this is analogous to initialization code of a unit, it's just the 'last' unit being initialized. Does the main program explicitly call the initialisation entry point of the (dynamically-loaded) library, or it this done by the OS? I was under the impression that the two were basically asynchronous and (as a particular example) both the program and the library would have distinct copies of the system unit with their own global variables etc. hence the memory manager problem. The memory manager problem is completely unrelated to this. DLL and calling program simply have different copies of the FPC memory manager. That is what needs to be solved with dynamic packages. As far as I know, the initialization entry point is called automatically. But the compiler experts should confirm this. IIRC the behaviour changed as the support for libraries improved; Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Michael Van Canneyt wrote: On Tue, 30 Sep 2014, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: On 29/09/2014 19:30, Reinier Olislagers wrote: Re bug report: agreed. I'll raise it. Jonas has already closed it, noting "http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx "*** The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. *** "I.e., what you are doing is unsupported ("must not call the LoadLibrary or LoadLibraryEx function"). I think that on most unix platforms, trying to load libraries from other the init function of other libraries is not supported either." However I'd precede that by a thought based on what Jose said. In your example, you're opening the database in the initialisation block of businesslayer.pas, which is invoked at an arbitrary position in the init sequence of the DLL/so. If that operation were moved instead to the initialisation block of testdbdll.lpr, which in the context of the DLL/so is analogous to a program's main block, it might work. No. this is not correct. For a library, this is analogous to initialization code of a unit, it's just the 'last' unit being initialized. Does the main program explicitly call the initialisation entry point of the (dynamically-loaded) library, or it this done by the OS? I was under the impression that the two were basically asynchronous and (as a particular example) both the program and the library would have distinct copies of the system unit with their own global variables etc. hence the memory manager problem. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On Tue, 30 Sep 2014, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: On 29/09/2014 19:30, Reinier Olislagers wrote: Re bug report: agreed. I'll raise it. Jonas has already closed it, noting "http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx "*** The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. *** "I.e., what you are doing is unsupported ("must not call the LoadLibrary or LoadLibraryEx function"). I think that on most unix platforms, trying to load libraries from other the init function of other libraries is not supported either." However I'd precede that by a thought based on what Jose said. In your example, you're opening the database in the initialisation block of businesslayer.pas, which is invoked at an arbitrary position in the init sequence of the DLL/so. If that operation were moved instead to the initialisation block of testdbdll.lpr, which in the context of the DLL/so is analogous to a program's main block, it might work. No. this is not correct. For a library, this is analogous to initialization code of a unit, it's just the 'last' unit being initialized. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Reinier Olislagers wrote: On 29/09/2014 19:30, Reinier Olislagers wrote: Re bug report: agreed. I'll raise it. Jonas has already closed it, noting "http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx "*** The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. *** "I.e., what you are doing is unsupported ("must not call the LoadLibrary or LoadLibraryEx function"). I think that on most unix platforms, trying to load libraries from other the init function of other libraries is not supported either." However I'd precede that by a thought based on what Jose said. In your example, you're opening the database in the initialisation block of businesslayer.pas, which is invoked at an arbitrary position in the init sequence of the DLL/so. If that operation were moved instead to the initialisation block of testdbdll.lpr, which in the context of the DLL/so is analogous to a program's main block, it might work. If having the open operation in testdbdll.lpr works but having it in businesslayer.pas doesn't, then it's fair to ask why in the context of FPC (hence my suggestion of a bug report). If neither works, then it's presumably explained by Jonas's note i.e. it's a "feature" in the context of the library loader. In practice, I still think it's best for the main program to tell the database when and how to initialise, since there's things that it might know about the user's intentions or environment that aren't known by the dynamically-loaded libraries (crude example: you might want to know the compile-time name of the project of which the main program was a part). -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 29/09/2014 19:30, Reinier Olislagers wrote: > Re bug report: agreed. I'll raise it. http://bugs.freepascal.org/view.php?id=26801 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Reinier Olislagers wrote: On 29/09/2014 17:41, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: On 29/09/2014 11:19, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: 2. In businesslayer.pas, $define CRASH to see the problem. The code in question is: initialization DBLayer:=TDBInterface.Create; finalization DBLayer.Free; ... so probably initialization order plays a part?!? How should I fix this? What happens if you move the responsibility for initialising and closing the database connection to the app-level code? In other words, the app does something like As the demo indicates, that does work (undefine CRASH). What I would like to know what is the cause of this problem - dlls being loaded before some kind - what kind? - of initialization is complete? Anyway, I'll keep digging; probably first looking at geting postgresql support in anyway. No, your example shows an implicit initialisation when the backend is accessed. Agreed... but as that code works there's no reason to suspect your approach won't work & my finished program sucesfully uses your approach ;) Re bug report: agreed. I'll raise it. Jose's comment about not (in effect) putting TIBConnection.Create() in the initialisation block of a program (hence of a DLL or .so) is interesting. Assuming that he is correct I think it's worth wondering /why/ he's correct, and if that is in fact a symptom of something wrong with the FPC initialisation sequence. If he's correct, I'd expect the problem to persist even if your businesslayer DLL were loaded on-demand rather than at the whim of the OS: the binary state of the DLL/so in memory would be inappropriate for reliable operation. If you still have problems when you call TIBConnection.Create() after all initialisation is complete, then you need to consider whether any state in the DLL/so has to be transferred to the main program. Hopefully you don't need to get involved with that. A final thing to consider is that if there is an asynchronous element in database initialisation it could end up being difficult for the main program to check that the DLL/so was ready to use. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 29/09/2014 17:41, Mark Morgan Lloyd wrote: > Reinier Olislagers wrote: >> On 29/09/2014 11:19, Mark Morgan Lloyd wrote: >>> Reinier Olislagers wrote: 2. In businesslayer.pas, $define CRASH to see the problem. The code in question is: initialization DBLayer:=TDBInterface.Create; finalization DBLayer.Free; ... so probably initialization order plays a part?!? How should I fix this? >>> What happens if you move the responsibility for initialising and closing >>> the database connection to the app-level code? In other words, the app >>> does something like >> As the demo indicates, that does work (undefine CRASH). >> >> What I would like to know what is the cause of this problem - dlls being >> loaded before some kind - what kind? - of initialization is complete? >> >> Anyway, I'll keep digging; probably first looking at geting postgresql >> support in anyway. > > No, your example shows an implicit initialisation when the backend is > accessed. Agreed... but as that code works there's no reason to suspect your approach won't work & my finished program sucesfully uses your approach ;) Re bug report: agreed. I'll raise it. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Reinier Olislagers wrote: On 29/09/2014 11:19, Mark Morgan Lloyd wrote: Reinier Olislagers wrote: 2. In businesslayer.pas, $define CRASH to see the problem. The code in question is: initialization DBLayer:=TDBInterface.Create; finalization DBLayer.Free; ... so probably initialization order plays a part?!? How should I fix this? What happens if you move the responsibility for initialising and closing the database connection to the app-level code? In other words, the app does something like As the demo indicates, that does work (undefine CRASH). What I would like to know what is the cause of this problem - dlls being loaded before some kind - what kind? - of initialization is complete? Anyway, I'll keep digging; probably first looking at geting postgresql support in anyway. No, your example shows an implicit initialisation when the backend is accessed. I was suggesting an explicit initialisation, so that the app can if necessary tell the backend what localisation conventions to use. OK, it's an excuse but it gets you out of the current hole. In the longer term I think this probably merits a bug report, so that library initialisation etc. can be explored. This does look like a sequencing issue rather than something being on the wrong heap. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 29/09/2014 16:51, José Mejuto wrote: > El 29/09/2014 a las #4, Reinier Olislagers escribió: > You must not initialize dbengine in the Initialization section and must > not finalize it in that place (maybe only as last chance) because > initialization order and finalization order is undefined by fpc and > finalization of your code could happen after the whole DB structure has > been finished, so the call to "DBLayer.Free" could try to free an object > controlled by an engine which is not loaded yet. Hi José, Thanks, I'll just add a note to the shared library page of the wiki. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
El 29/09/2014 a las #4, Reinier Olislagers escribió: What I would like to know what is the cause of this problem - dlls being loaded before some kind - what kind? - of initialization is complete? Anyway, I'll keep digging; probably first looking at geting postgresql support in anyway. ___ Hello, You must not initialize dbengine in the Initialization section and must not finalize it in that place (maybe only as last chance) because initialization order and finalization order is undefined by fpc and finalization of your code could happen after the whole DB structure has been finished, so the call to "DBLayer.Free" could try to free an object controlled by an engine which is not loaded yet. -- ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 29/09/2014 11:19, Mark Morgan Lloyd wrote: > Reinier Olislagers wrote: > What happens if you move the responsibility for initialising and closing > the database connection to the app-level code? In other words, the app > does something like Ok, after eliminating some PEBKAC, my real dll works flawlessly. Still would like to know the background to this but glad it works. Thanks a lot, Mark! Regards, Reinier ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
On 29/09/2014 11:19, Mark Morgan Lloyd wrote: > Reinier Olislagers wrote: >> 2. In businesslayer.pas, $define CRASH to see the problem. >> The code in question is: >> initialization >> DBLayer:=TDBInterface.Create; >> >> finalization >> DBLayer.Free; >> ... so probably initialization order plays a part?!? >> >> How should I fix this? > > What happens if you move the responsibility for initialising and closing > the database connection to the app-level code? In other words, the app > does something like As the demo indicates, that does work (undefine CRASH). What I would like to know what is the cause of this problem - dlls being loaded before some kind - what kind? - of initialization is complete? Anyway, I'll keep digging; probably first looking at geting postgresql support in anyway. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Reproducible code: DLL calling Firebird crashes
Reinier Olislagers wrote: Apparently my crashes in a dll that use Firebird have to do with initialization sections in my business layer creating a single instance of my db layer. Distilled reproducible code that demonstrates problem: https://bitbucket.org/reiniero/fpc_laz_patch_playground/downloads/dllcrash.zip 1. Please update your Firebird server details in dbinterface.pas to your situation (hostname etc) 2. In businesslayer.pas, $define CRASH to see the problem. The code in question is: initialization DBLayer:=TDBInterface.Create; finalization DBLayer.Free; ... so probably initialization order plays a part?!? How should I fix this? What happens if you move the responsibility for initialising and closing the database connection to the app-level code? In other words, the app does something like writeln('Starting demo'); writeln('TheAnswer is:'); InitialiseBackend; try writeln(TheAnswer) finally FinaliseBackend end; writeln('Ending demo'); -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal