New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change proposal for win32/vmem.h #16351
Comments
From keuchel@rainer-keuchel.deI had a problems with Inline::CPP on Windows/MingW. DLLs built with Inline::CPP use msvcrt malloc/free. When USE_LINKED_LIST is defined in vmem.h I would suggest to check if the pointer to free belongs to the process heap With this change everything is fine.. void VMem::Free(void* pMem)
{
#ifdef _USE_LINKED_LIST
if (pMem) {
size_t s;
HANDLE hHeap;
PMEMORY_BLOCK_HEADER ptr =
(PMEMORY_BLOCK_HEADER)(((char*)pMem)-sizeof(MEMORY_BLOCK_HEADER));
if (ptr->owner != this) {
* // can be block from msvcrt malloc when using Inline::CPP!**
** hHeap = GetProcessHeap();**
** s = HeapSize(hHeap, 0, pMem);**
**
** if(s == (size_t) -1)**
** {**
** dTHX;**
** Perl_warn(aTHX_ "ptr %p is not alloc'ed from msvcrt malloc",
pMem);**
** }**
** else**
** {**
** //dTHX;**
** //Perl_warn(aTHX_ "ptr %p is alloc'ed from msvcrt malloc",
pMem);**
** m_pfree(pMem);**
** return;**
** }**
***
if (ptr->owner) {
#if 1
dTHX;
int *nowhere = NULL;
Perl_warn(aTHX_ "Free to wrong pool %p not
%p",this,ptr->owner);
*nowhere = 0; /* this segfault is deliberate,
so you can see the stack trace */
#else
ptr->owner->Free(pMem);
#endif
}
return;
}
GetLock();
UnlinkBlock(ptr);
ptr->owner = NULL;
m_pfree(ptr);
FreeLock();
}
#else
m_pfree(pMem);
#endif
} |
From @bulk88On Sun, 07 Jan 2018 10:48:37 -0800, keuchel@rainer-keuchel.de wrote:
Calling HeapSize on random pointers, with there being NO guarantee the pointer was allocated by the kernel32.dll heap allocater isn't safe. While modern (>= Vista or XP) checksum/XOR the 8/16 byte malloc header before pointer to detect corruption, that is implementation specific and undependable. I think your problem is Inline::CPP doesnt do a #include "XSUB.h", so the #define free(x) never happens that most Win32 XS code has that maps the free token to perl's own allocator. It is a long running problem on Win32 perl. I think the original reason for hooking free() in XS code was for ithread/psuedo-fork cleanup/anti-leaking on psuedo-proc exit so perl can cleanly free "global" pointers from C-ish (not using perl data structures) XS code that keep things allocated forever because it assumes the OS will clean it up on process exit (but perl has psuedo-procs). That linked list code also smoothes over any P5P memory leaks that perl_destruct doesn't free by accident. There is yet another problem about multiple CRTs in a process and they generate their own Kernel32 Heap objects/pools too, they dont use heap returned by GetProcessHeap. Use VMMap tool on a perl process, click orange Heap, then in the bottom there will be atleast 2 heap IDs (AKA pools), one is GetProcessHeap, other is CRT specific and Perl uses that. If you wind up in CRT hell, each new CRT in the process will make its own pool. Many 3rd party and MS DLLs like to make their Heap pools too. Some C libraries like to add their own header to an object/allocation they give you and they dont give you a pointer to the start of the allocation but a pointer to somewhere inside the allocation. These libraries also tell you to free the resource ONLY by using their functions, not a generic ISO C free(). You need to figure out what is going on with the headers, make a .i file, run it through gnu indent, and figure out if your Inline::CPP code is perl/XS aware or not and what is the final C symbol name of the callsite of that free() in your code. "NO_XSLOCKS" is the define that usually turns off perl hooking C std lib functions. -- |
The RT System itself - Status changed from 'new' to 'open' |
Barring a further response from the reporter, I'm closing this ticket for now. |
Migrated from rt.perl.org#132690 (status was 'open')
Searchable as RT132690$
The text was updated successfully, but these errors were encountered: