Skip to content

Commit 01585a7

Browse files
committed
Deallocate resources for DacDbiArrayList with a matching deallocator
1 parent f2d6cd3 commit 01585a7

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed

src/coreclr/debug/daccess/dacdbiimpl.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ IDacDbiInterface::IAllocator * g_pAllocator = NULL;
7878
// return; // DBI will then free this memory.
7979
// }
8080
// ...
81-
// DeleteDbiMemory(p);
81+
// DeleteDbiMemory(p); // DeleteDbiMemory(p, len); if it was an array allocation.
8282
// }
8383
//
8484
// Be very careful when using this on classes since Dbi and DAC may be in
@@ -155,6 +155,25 @@ template<class T> void DeleteDbiMemory(T *p)
155155
g_pAllocator->Free((BYTE*) p);
156156
}
157157

158+
// Delete memory and invoke dtor for memory allocated with 'operator (forDbi) new[]'
159+
// There's an inherent risk here - where each element's destructor will get called within
160+
// the context of the DAC. If the destructor tries to use the CRT allocator logic expecting
161+
// to hit the DBI's, we could be in trouble. Those objects need to use an export allocator like this.
162+
template<class T> void DeleteDbiArrayMemory(T *p, int len)
163+
{
164+
if (p == NULL)
165+
{
166+
return;
167+
}
168+
169+
for (T *cur = p; cur < p + len; cur++)
170+
{
171+
cur->~T();
172+
}
173+
174+
_ASSERTE(g_pAllocator != NULL);
175+
g_pAllocator->Free((BYTE*) p);
176+
}
158177

159178
//---------------------------------------------------------------------------------------
160179
// Creates the DacDbiInterface object, used by Dbi.
@@ -818,12 +837,6 @@ SIZE_T DacDbiInterfaceImpl::GetArgCount(MethodDesc * pMD)
818837
return NumArguments;
819838
} //GetArgCount
820839

821-
// Allocator to pass to DebugInfoStores, allocating forDBI
822-
BYTE* InfoStoreForDbiNew(void * pData, size_t cBytes)
823-
{
824-
return new(forDbi) BYTE[cBytes];
825-
}
826-
827840
// Allocator to pass to the debug-info-stores...
828841
BYTE* InfoStoreNew(void * pData, size_t cBytes)
829842
{

src/coreclr/debug/di/rspriv.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ extern forDbiWorker forDbi;
173173
// for dbi we just default to new, but we need to have these defined for both dac and dbi
174174
inline void * operator new(size_t lenBytes, const forDbiWorker &)
175175
{
176-
void * result = new BYTE[lenBytes];
176+
void * result = new (nothrow) BYTE[lenBytes];
177177
if (result == NULL)
178178
{
179179
ThrowOutOfMemory();
@@ -183,7 +183,7 @@ inline void * operator new(size_t lenBytes, const forDbiWorker &)
183183

184184
inline void * operator new[](size_t lenBytes, const forDbiWorker &)
185185
{
186-
void * result = new BYTE[lenBytes];
186+
void * result = new (nothrow) BYTE[lenBytes];
187187
if (result == NULL)
188188
{
189189
ThrowOutOfMemory();
@@ -198,6 +198,11 @@ void DeleteDbiMemory(T *p)
198198
delete p;
199199
}
200200

201+
template<class T> inline
202+
void DeleteDbiArrayMemory(T *p, int)
203+
{
204+
delete[] p;
205+
}
201206

202207

203208
//---------------------------------------------------------------------------------------

src/coreclr/debug/inc/dacdbiinterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
// In the DBI implementation, this can directly call delete (assuming the IAllocator::Free
3030
// directly called new).
3131
template<class T> void DeleteDbiMemory(T *p);
32+
template<class T> void DeleteDbiArrayMemory(T *p, int len);
3233
// Need a class to serve as a tag that we can use to overload New/Delete.
3334
class forDbiWorker {};
3435
extern forDbiWorker forDbi;

src/coreclr/debug/inc/dacdbistructures.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void DacDbiArrayList<T>::Dealloc()
7171

7272
if (m_pList != NULL)
7373
{
74-
delete [] m_pList;
74+
DeleteDbiArrayMemory(m_pList, m_nEntries);
7575
m_pList = NULL;
7676
}
7777
m_nEntries = 0;

0 commit comments

Comments
 (0)