Alvaro Herrera wrote:
Craig Ringer wrote:

That said, PostgreSQL does appear to use its own allocator for memory passed across library boundaries, and if it doesn't pass any FILE pointers across library boundaries either then that's the worst two problems that arise with a C runtime mismatch taken care of. As far as I know, anyway, and I've had the misfortune to have to dig into it a bit.

Note that our allocator uses malloc() underneath.

Sure. That's fine, so long as the wrapper functions palloc and pfree are real functions that reside in the same DLL on windows. You can pass pointers around freely, otherwise you couldn't do much at all ... the problem is with a call path like this:

- DLL2 calls a function in DLL1
- DLL1 malloc()'s some memory and returns a pointer to it
- DLL2 free()'s the pointer

My understanding of the reason that this breaks if DLL1 and DLL2 are linked to different C runtimes is that it's essentially a double free plus a memory leak. The allocator in DLL2 has never allocated the memory so the free call is freeing unallocated memory. It's never properly freed by the allocator in DLL2, so it's leaked as far as that allocator is concerned. It's quite possible that my understanding of the problem isn't correct, though.

In any case, the safe thing to do is:

- DLL2 calls a function in DLL1
- DLL1 malloc()'s some memory and returns a pointer to it
- DLL2 calls a free() wrapper function defined in DLL1
- The free() wrapper in DLL1 calls the real free() to release the memory

If palloc() and pfree() are real functions defined in the same DLL, then it should be just fine as use of them will ensure that everything uses the same underlying memory allocator. A problem might arise if Pg ever passes memory not allocated with palloc() around, though.

It looks like palloc is a macro for the real function MemoryContextAlloc, and pfree is just a real function - so it should be fine. They don't expose references to malloc() and free() directly.

This actually applies to any situation in which multiple malloc()/free() implementations are used - but most people and platforms are sane enough to avoid that.

And I would think
that we do pass FILE pointers around too; AllocateFile works with FILE,
so any library that's using that method to get to files would be in
trouble (which they should, because it's the way to ensure we don't leak
files on transaction abort and also to ensure that the system continues
to work on the face of lots of open files).

Yep, I'm pretty sure that'll cause issues when using a mingw-compiled object in a msvc++-compiled copy of Pg.

--
Craig Ringer


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

Reply via email to