Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
C çalışma zamanı kitaplığını kullanan bir programın hatalarını ayıkladığınızda, bu hata ayıklama teknikleri yararlı olabilir.
CRT hata ayıklama kitaplığı kullanımı
C çalışma zamanı (CRT) kitaplığı kapsamlı hata ayıklama desteği sağlar. CRT hata ayıklama kitaplıklarından birini kullanmak için , veya/DEBUG/MDd/MTdgerekir.
CRT hata ayıklama için ana tanımlar ve makrolar üst bilgi dosyasında bulunabilir <crtdbg.h> .
CRT hata ayıklama kitaplıklarındaki işlevler hata ayıklama bilgileriyle (/Z7, /Zd, /Zi, /ZI (Hata Ayıklama Bilgileri Biçimi)) ve iyileştirme olmadan derlenir. Bazı işlevler, kendilerine geçirilen parametreleri doğrulamak için onaylar içerir ve kaynak kodu sağlanır. Bu kaynak koduyla, işlevlerin beklediğiniz gibi çalıştığını onaylamak ve hatalı parametreleri veya bellek durumlarını denetlemek için CRT işlevlerine adım atabilirsiniz. (Bazı CRT teknolojileri özeldir ve özel durum işleme, kayan nokta ve diğer birkaç yordam için kaynak kodu sağlamaz.)
Kullanabileceğiniz çeşitli çalışma zamanı kitaplıkları hakkında daha fazla bilgi için bkz . C Çalışma Zamanı Kitaplıkları.
Raporlama makroları
Hata ayıklama için, deyimlerinin kullanımını _RPTn değiştirmek için içinde _RPTFntanımlanan ve <crtdbg.h> makrolarını kullanabilirsinizprintf. Tanımlanmadığında #ifdef yayın derlemenizde otomatik olarak kaybolduklarından, bunları _DEBUG yönergelere dahil etmeniz gerekmez.
| Makro | Açıklama |
|---|---|
_RPT0, _RPT1, _RPT2, _RPT3, , _RPT4 |
Bir ileti dizesi ve sıfırdan dörte kadar bağımsız değişken verir. aracılığıyla _RPT1_RPT4için, ileti dizesi bağımsız değişkenler için printf stili bir biçimlendirme dizesi işlevi görür. |
_RPTF0, _RPTF1, _RPTF2, _RPTF3, , _RPTF4 |
ile _RPTnaynıdır, ancak bu makrolar makronun bulunduğu dosya adını ve satır numarasını da verir. |
Aşağıdaki örneği inceleyin:
#ifdef _DEBUG
if ( someVar > MAX_SOMEVAR )
printf( "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n",
someVar, otherVar );
#endif
Bu kod, ve someVar değerlerinin otherVar çıkışını verirstdout. Bu değerleri ve ayrıca dosya adını ve satır numarasını bildirmek için _RPTF2 aşağıdaki çağrıyı kullanabilirsiniz:
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, "In NameOfThisFunc( ), someVar= %d, otherVar= %d\n", someVar, otherVar );
Bazı uygulamaların C çalışma zamanı kitaplığıyla sağlanan makroların sağlamadığını bildiren hata ayıklaması gerekebilir. Bu durumlarda, özel olarak kendi gereksinimlerinize uyacak şekilde tasarlanmış bir makro yazabilirsiniz. Örneğin, üst bilgi dosyalarınızdan birine adlı ALERT_IF2bir makro tanımlamak için aşağıdaki gibi bir kod ekleyebilirsiniz:
#ifndef _DEBUG /* For RELEASE builds */
#define ALERT_IF2(expr, msg, arg1, arg2) do {} while (0)
#else /* For DEBUG builds */
#define ALERT_IF2(expr, msg, arg1, arg2) \
do { \
if ((expr) && \
(1 == _CrtDbgReport(_CRT_ERROR, \
__FILE__, __LINE__, msg, arg1, arg2))) \
_CrtDbgBreak( ); \
} while (0)
#endif
bir çağrısı ALERT_IF2 kodun tüm işlevlerini printf gerçekleştirebilir:
ALERT_IF2(someVar > MAX_SOMEVAR, "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n", someVar, otherVar );
Özel makroları kolayca değiştirerek farklı hedeflere daha fazla veya daha az bilgi bildirebilirsiniz. Hata ayıklama gereksinimleriniz geliştikçe bu yaklaşım yararlıdır.
Hata ayıklama kanca işlevi yazma
Kodunuzu hata ayıklayıcının normal işlemesinde önceden tanımlanmış bazı noktalara eklemenize olanak sağlayan çeşitli türlerde özel hata ayıklama kancası işlevleri yazabilirsiniz.
İstemci blok kanca işlevleri
Bloklarda _CLIENT_BLOCK depolanan verilerin içeriğini doğrulamak veya raporlamak istiyorsanız, özellikle bu amaçla bir işlev yazabilirsiniz. Yazdığınız işlevin içinde tanımlandığı <crtdbg.h>gibi aşağıdakine benzer bir prototipi olmalıdır:
void YourClientDump(void *, size_t)
Başka bir deyişle, kanca işleviniz ayırma bloğunun başlangıcına yönelik bir void işaretçiyi kabul etmeli ve ayırmanın boyutunu belirten bir size_t tür değeriyle birlikte döndürmelidir void. Aksi takdirde içeriği size bağlı olur.
Kanca işlevinizi _CrtSetDumpClient kullanarak yükledikten sonra, her _CLIENT_BLOCK blok atıldığında çağrılır. Ardından , _CrtReportBlockType kullanarak atılan blokların türü veya alt türü hakkında bilgi alabilirsiniz.
İşlevinizin geçişini _CrtSetDumpClient yaptığınız işaretçi, içinde _CRT_DUMP_CLIENTtanımlandığı gibi türündedir<crtdbg.h>:
typedef void (__cdecl *_CRT_DUMP_CLIENT)
(void *, size_t);
Atama kanca işlevleri
kullanılarak _CrtSetAllocHookyüklenen ayırma kancası işlevi, bellek her ayrıldığında, yeniden ayrıldığında veya serbest bırakıldığında çağrılır. Bu tür kancaları birçok farklı amaçla kullanabilirsiniz. Bir uygulamanın, ayırma düzenlerini incelemek veya daha sonra çözümlemek üzere günlük ayırma bilgilerini incelemek gibi yetersiz bellek durumlarını nasıl işlediğini test etmek için bunu kullanın.
Not
Ayırma kancaları ve crt bellek ayırmaları bölümünde açıklanan bir ayırma kanca işlevinde C çalışma zamanı kitaplık işlevlerini kullanma kısıtlamasına dikkat edin.
Ayırma kancası işlevinin aşağıdaki örneğe benzer bir prototipi olmalıdır:
int YourAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine )
geçirdiğiniz _CrtSetAllocHook işaretçi, içinde _CRT_ALLOC_HOOKtanımlandığı gibi türündedir<crtdbg.h>:
typedef int (__cdecl * _CRT_ALLOC_HOOK)
(int, void *, size_t, int, long, const unsigned char *, int);
Çalışma zamanı kitaplığı kancanızı çağırdığında, nAllocType bağımsız değişken hangi ayırma işleminin (, _HOOK_ALLOCveya _HOOK_REALLOC) yapılmak_HOOK_FREE üzere olduğunu gösterir. Serbest veya yeniden konumlandırmada, pvData serbest olmak üzere olan bloğun kullanıcı makalesine bir işaretçisi vardır. Ancak ayırma işlemi gerçekleşmediğinden bu işaretçi null değeridir. Kalan bağımsız değişkenler ayırmanın boyutunu, blok türünü, sıralı istek numarasını ve dosya adına yönelik bir işaretçiyi içerir. Varsa, bağımsız değişkenler ayırmanın yapıldığı satır numarasını da içerir. Kanca işlevi, yazarının istediği çözümlemeyi ve diğer görevleri gerçekleştirdikten sonra, ayırma işleminin devamebileceğini TRUEbelirten veya işlemin başarısız olması gerektiğini belirten öğesini döndürmelidirFALSE. Bu türdeki basit bir kanca, şimdiye kadar ayrılan bellek miktarını denetleyebilir ve bu miktar küçük bir sınırı aşarsa geri dönebilir FALSE . Uygulama daha sonra normalde yalnızca kullanılabilir bellek düşük olduğunda ortaya çıkabilecek ayırma hataları türüyle karşılaşır. Daha karmaşık kancalar ayırma desenlerini izleyebilir, bellek kullanımını analiz edebilir veya belirli durumlar oluştuğunda rapor verebilir.
Ayırma kancaları ve CRT bellek ayırmaları
Ayırma kancası işlevlerinde önemli bir kısıtlama, blokları açıkça yoksaymaları _CRT_BLOCK gerektiğidir. Bu bloklar, iç belleği ayıran C çalışma zamanı kitaplığı işlevlerine çağrı yaparsa, C çalışma zamanı kitaplığı işlevleri tarafından dahili olarak yapılan bellek ayırmalarıdır. Ayırma kancası işlevinizin başına aşağıdaki kodu ekleyerek blokları yoksayabilirsiniz _CRT_BLOCK :
if ( nBlockUse == _CRT_BLOCK )
return( TRUE );
Ayırma kancanız blokları yoksayarsa _CRT_BLOCK , kancanızda çağrılan herhangi bir C çalışma zamanı kitaplığı işlevi programı sonsuz bir döngüde yakalayabilir. Örneğin, printf iç ayırma yapar. Kanca kodunuz öğesini çağırırsa printf, sonuçta elde edilen ayırma kancanızın yeniden çağrılmasına neden olur; bu, yığın taşana kadar yeniden çağrılır printf ve bu şekilde devam eder. Ayırma işlemlerini bildirmeniz _CRT_BLOCK gerekiyorsa, bu kısıtlamayı aşmanın bir yolu, biçimlendirme ve çıkış için C çalışma zamanı işlevleri yerine Windows API işlevlerini kullanmaktır. Windows API'leri C çalışma zamanı kitaplığı yığınını kullanmadığından, ayırma kancanızı sonsuz bir döngüde yakalamaz.
Çalışma zamanı kitaplığı kaynak dosyalarını incelerseniz, varsayılan ayırma kancası işlevinin _CrtDefaultAllocHook (yalnızca döndürür TRUE) kendi debug_heap_hook.cppayrı bir dosyasında bulunduğunu görürsünüz. Uygulamanızın main işlevinden önce yürütülen çalışma zamanı başlangıç kodu tarafından yapılan ayırmalar için bile ayırma kancanızın çağrılmasını istiyorsanız, bu varsayılan işlevi kullanmak _CrtSetAllocHookyerine kendi işlevlerinden biriyle değiştirebilirsiniz.
Kanca işlevlerini raporlama
kullanılarak _CrtSetReportHookyüklenen bir rapor kancası işlevi, her _CrtDbgReport hata ayıklama raporu oluşturulduğunda çağrılır. Raporları belirli ayırma türlerine odaklanmak üzere filtrelemek için diğer özelliklerin dışında bunu kullanabilirsiniz. Bir rapor kancası işlevinin aşağıdaki örneğe benzer bir prototipi olmalıdır:
int AppReportHook(int nRptType, char *szMsg, int *retVal);
geçirdiğiniz _CrtSetReportHook işaretçi, içinde _CRT_REPORT_HOOKtanımlandığı gibi türündedir<crtdbg.h>:
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
Çalışma zamanı kitaplığı kanca işlevinizi çağırdığında, nRptType bağımsız değişken raporun (_CRT_WARN, veya _CRT_ERROR) _CRT_ASSERT kategorisini içerir, szMsgtam olarak derlenmiş bir rapor ileti dizesine yönelik bir işaretçi içerir ve retVal raporu oluşturduktan sonra normal yürütmeye devam mı _CrtDbgReport yoksa hata ayıklayıcıyı başlatma mı gerektiğini belirtir. (Sıfır retVal değeri yürütmeye devam eder, 1 değeri hata ayıklayıcısını başlatır.)
Kanca söz konusu iletiyi tamamen ele alırsa, başka raporlama gerekmemesi için döndürmelidir TRUE. döndürürse FALSE, _CrtDbgReport iletiyi normal şekilde bildirir.
Bu bölümde
Öbek atama işlevleri hata ayıklama sürümleri
Öbek ayırma işlevlerinin özel Hata Ayıklama sürümlerini açıklar: CRT'nin çağrıları, bunları açıkça çağırmanın avantajları, dönüştürmeyi önleme, istemci bloklarındaki ayrı ayırma türlerini izleme ve tanımlanmama
_DEBUGsonuçları.CRT hata ayıklama öbeği ayrıntıları
Bellek yönetimini ve hata ayıklama yığınını, hata ayıklama yığınındaki blok türlerini, yığın durumu raporlama işlevlerini ve ayırma isteklerini izlemek için hata ayıklama yığınının nasıl kullanılacağını açıklar.
CRT kitaplığını kullanarak bellek sızıntılarını bulma
Hata ayıklayıcısını ve C Çalışma Zamanı Kitaplığı'nı kullanarak bellek sızıntılarını algılama ve yalıtma tekniklerini kapsar.