2010-03-15 11 views
6

Programım içinde büyük bellek sızıntıları olan üçüncü taraf bir dinamik bağlantı kitaplığı kullanıyor. Hem programım hem de kütüphane Visual C++ yerel kodudur. Her ikisi de Visual C++ çalışma zamanına dinamik olarak bağlanır.Visual C++ çalışma zamanını başka bir yığına değiştirebilir miyim?

Kitaplık kodu çalışırken Visual C++ çalışma zamanı aracılığıyla gerçekleştirilen tüm ayırmaların bu yığında yapılması için kütüphaneyi başka bir yığına zorlamak isterim. HeapCreate() ve daha sonra HeapDestroy() numaralı telefonu arayabilirim. Bir şekilde tüm tahsislerin yeni yığında yapılmasını sağlarım, artık sızıntıları umursamıyorum - hepsi ikinci yığını yok ettiğimde giderler.

Visual C++ çalışma zamanını, belirtilen bir yığında tüm ayırma yapmak için zorlamak mümkün mü?

+0

nasıl kütüphaneye bağlantı veriyor? – GManNickG

+0

@GMan: Program kütüphaneye dinamik olarak bağlanır. – sharptooth

+0

DLL çalışma zamanına nasıl bağlanır? –

cevap

3

Maalesef benim son cevap tam olarak Neyse heres o ... yarı pişmiş, i sekmesini preslenmiş ve bu bir metin kutusu değil bir editör oldu hatırlamadan girmek

edildik:

kullanabilirsiniz ve tahsisat fonksiyonlarını kanca kendi bunların yerine kütüphane dolambaçlar:

böyle

Belli belirsiz bir şey:

//declare a global 
HANDLE g_currentHeap; 

LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) 
{ 
    return OriginalHeapAlloc(g_currentHeap, dwFlags, dwBytes); 
} 


BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) 
{ 
    return OriginalHeapFree(g_currentHeap, dwFlags, lpMem); 
} 

Uygulama yükü Sonra

HANDLE g_Heaps[2]; 

int main() 
{ 
    // Two heaps 
    g_Heaps[0] = HeapCreate(...); 
    g_Heaps[1] = HeapCreate(...); 


    // Do whatevers needed to hook HeapAlloc and HeapFree and any other heap functions 
    // and redirect them to the versions above 
    // Save the old function pointers so we can call them 
} 

her sen 3. parti DLL'den bir API çağırmak içinde size sorunun bu

void someFn() 
{ 
    g_currentHeap = g_Heaps[1]; 
    Some3rdPartyAPI(); 
    g_currentHeap = g_Heaps[0]; 

    SomeOtherFunction(); 

} 

Bu çözecektir

@peterchen yapabilirsiniz: C++ çalışma zamanı HeapAlloc çağırır Yeni ve malloc() için bu yaklaşım işe yarayacak. Aslında, hemen hemen her dil çalışma zamanının özel bir neden olmadığı sürece win32 Heap fonksiyonlarını kullanacağına inanıyorum.

+0

En azından VC6'da, HeapAlloc, her zaman, msol tahsisleri için başlatılan özel bir bellek yöneticisi olan Release Build'lerde, Debug Builds içinde çağrıldı. * Bilmiyorum * VS2005/2008'de bu durum değiştiyse - doğrulanması gerekiyor. Visual Studio 8 için CRT kaynak HeapAlloc çağırmak gibi görünüyor – peterchen

+0

() I) ( her malloc'dan üzerine çağrıldığı görünüyor .... bir test programı sürüm modunda HeapAlloc() bir kesme noktası koymak Ve yeni. –

+0

Detours çok kullanışlıdır, ancak özellikle birden fazla iş parçacığı olduğunda dikkatli olunması gerekir. Onunla hata ayıklama konusunda bazı çok zorlu sorunlarla karşılaştım. En iyi bahis, kullanmayı tercih ederseniz, diğer DLL'leri yüklemeden veya ana disk dışındaki herhangi bir parçayı başlatmadan önce tüm dolambaçlı fonksiyonlarınızı başlatmak ve ayarlamaktır. Eğer başka bir iş parçacığı zaten işlevini saptırmaya çalıştığınız zor durumlarda içine alabilirsiniz. – cpalmer

0

Her iki ikili de aynı şekilde bağlanırsa, DLL'nin tahsisleri yalnızca 'un yönlendirilmesi en iyi yanıltıcıdır.

Düşündüğüm en sağlam yol, DLL'yi ayrı bir işlem haline getirmektir. Sadece IDispatch arabirimlerini kullanan bir COM DLL için oldukça kolay veya bir proxy/stub DLL sağlar. Aksi halde, özel bir sarıcı yazmanız gerekir - çok fazla iş içeren DLL API'sine bağlı olarak veya bir performans sorunu olabilir.

işlem içi kalmasını gerektiriyorsa

, CRT tahsisleri kanca ve (örneğin, bir Win32 yığın gibi) başka ayırıcı kütüphaneye yapılan tahsisleri yönlendirmek başladı.

mayın/VKG karar global bayrağını ayarlar kütüphaneye tüm çağrıları sarma yapılabilir en güvenli olacaktır. Alternatif olarak, yığın kümesini inceleyebilirsiniz - ancak bu, tüm senaryolarda çalışmaz. Her iki çözümle kodunuzda uygulanan ancak kütüphane tarafından aranan geri arama için dikkat edin.

[değiştir] _CRTSetAllocHook sadece olsa hata ayıklama buils içinde çalışır.

+0

Koparma atanması, CRT'nin hata ayıklamayan sürümü için çalışır mı? – sharptooth

+0

Haklısınız, _CrtSetDebugHook, yalnızca hata ayıklama yapılarında da çalışır. Tüm tahsisler için sürüm oluşturmada çalışıyorlarsa rep_movsd tarafından önerilen şekilde detourları kontrol edebilirsiniz. Aksi takdirde ... hızlı bir Google, kesin bir şey ortaya çıkarmaz. Belki diğer cevapları bekle ya da yeni bir soru olarak aç. – peterchen

İlgili konular