Aracılığıyla paylaş


crt Debug öbek

Bu konu, crt hata ayıklama öbek ayrıntılı bir bakış sağlar.

Bu konuda

Bellek yönetimi ve hata ayıklama öbek

Hata ayıklama öbek üzerindeki blok türlerine

Yığın hata ayıklama özellikleri

Hata ayıklama öbek kullanma

Yeni, silme ve C++'ta _CLIENT_BLOCKs debug öbek

Öbek durumu raporlama işlevleri

Yığın ayırma istekleri izleme

Bellek yönetimi ve hata ayıklama öbek

(Artık gerekli sonra Tahsisatları boşaltmak başarısız) ayrılmış bir arabellek ve bellek sızıntıları sonuna iki programcılarının karşılaştığı en yaygın ve gerçeði sorunları üzerine.Hata ayıklama öbek bu tür bellek ayırma ile ilgili sorunları çözmek için güçlü araçlar sunar.

Yığın işlevlerin sürümleri sürümde kullanılan standart veya temel sürümleri çağrısı hata ayıklama oluşturur.Bir bellek bloğu istediğinde, hata ayıklama yığın yöneticisinin temel öbekten biraz daha büyük bir o bölümüne bir işaretçi döndürür ve istenen bellek bloğu ayırır.Örneğin, uygulamanın içerdiği arama varsayalım: malloc( 10 ).Bir yayın yapısı içinde malloc isteyen bir ayırma 10 bayt temel yığın ayırma yordamı çağırırsınız.Bir hata ayıklama yapıda, ancak, malloc çağıracak _malloc_dbg, hangi sonra çağrı bir ayırma 10 bayt artı ek bellek yaklaşık olarak 36 baytını isteyen temel yığın ayırma yordamı.Hata ayıklama yığınındaki tüm ortaya çıkan bellek blokları, kendilerine tahsis göre sıralanmış bir tek bağlantılı liste bağlanır.

Bağlantı hata ayıklama bellek blokları birlikte ve veri yakalamak için her iki tarafındaki küçük arabellekleri için Yazar tahsis edilen bölge, işaretçileri için muhasebe bilgi için hata ayıklama yığın yordamları tarafından ayrılan ek bellek kullanılır.

Şu anda, hata ayıklama öbek 's muhasebe bilgilerini depolamak için kullanılan blok başlık yapısı içinde DBGINT gibi bildirilir.H üstbilgi dosyası:

typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
    struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
    struct _CrtMemBlockHeader *pBlockHeaderPrev;
    char *szFileName;    // File name
    int nLine;           // Line number
    size_t nDataSize;    // Size of user block
    int nBlockUse;       // Type of block
    long lRequest;       // Allocation number
// Buffer just before (lower than) the user's memory:
    unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;

/* In an actual memory block in the debug heap,
 * this structure is followed by:
 *   unsigned char data[nDataSize];
 *   unsigned char anotherGap[nNoMansLandSize];
 */

NoMansLand Blok kullanıcı veri alanındaki her iki tarafındaki arabellek 4 bayt boyutunda olan ve kullanıcının bellek bloğu sınırları değil üzerine yazılmış olduğunu doğrulamak için hata ayıklama yığın yordamlar tarafından kullanılan bilinen bayt değeri ile doldurulur.Hata ayıklama öbek de yeni bellek blokları bilinen bir değerle doldurur.Aşağıda açıklandığı şekilde boşaltılmış blokları öbek 's bağlantılı listede tutmak seçerseniz, boşaltılmış Bu bloklar da bilinen bir değerle doldurulur.Şu anda kullanılan gerçek bayt değerleri şunlardır:

  • NoMansLand (0xFD)
    "NoMansLand" her iki tarafında bir uygulama tarafından kullanılan bellek arabellekleri şu anda 0xFD ile doldurulur.

  • Boşaltılmış blokları (0xDD)
    Hata ayıklama yığın içinde kullanılmayan tutulan boşaltılmış blokları bağlı liste ne zaman _CRTDBG_DELAY_FREE_MEM_DF bayrağı ayarlı şu anda 0xDD ile doldurulur.

  • Yeni nesneler (0xCD)
    Yeni nesneler ayrıldıkları zaman 0xCD ile doldurulmuştur.

    Bu konuda

Hata ayıklama öbek üzerindeki blok türlerine

Her hata ayıklama Öbek bellek bloğunda beş ayırma türlerinden birine atanır.Bu türleri izleniyor ve sızıntı algılaması ve durumu Raporlama amaçları için farklı bildirdi.Bir bloğun türü gibi doğrudan arama hata ayıklama yığın ayırma işlevlerinden birini kullanarak ayırarak belirtebilirsiniz _malloc_dbg.Beş tür hata ayıklama yığınındaki bellek blokları (set nBlockUse üyesi _CrtMemBlockHeader yapısı) aşağıdaki gibidir:

  • _NORMAL_BLOCK
    Çağrı malloc veya calloc Normal bir blok oluşturur.Yalnızca Normal blokları kullanır ve istemci blokları gerek yok düşünüyorsanız tanımlamak isteyebilirsiniz _crtdbg_map_alloc, tüm yığın ayırma neden olan hata ayıklama yapıları içinde hata ayıklama eşdeğerlerine eşlenmesi için çağırır.Bu dosya adı ve satır numarası bilgilerini ilgili öbeği üstbilgisi içinde depolanan her ayırma görüşmesiyle ilgili izin verir.

  • _CRT_BLOCK
    Ayrı olarak yönetilebilir şekilde dahili olarak birçok çalışma zamanı kitaplığı işlevleri tarafından ayrılan bellek blok blok crt işaretlenir.Sonuç olarak, sızıntı algılaması ve diğer işlemleri onlar tarafından etkilenmez.Tahsisat gerekir hiçbir zaman ayırmak, yeniden tahsis veya crt türü herhangi bir bloğu serbest.

  • _CLIENT_BLOCK
    Bir uygulama verilen bir grup olarak bu tür bir bellek bloğu, açýk çaðrýlar yığın hata ayıklama işlevlerini kullanarak ayırarak hata ayıklama amacıyla ayırmaları özel izini tutabilirsiniz.mfc, örneğin, ayırır tüm CObjects olarak istemci bloklar; diğer uygulamalardan farklı bellek nesneleri istemci bloklar halinde kalmasına neden olacaktır.İstemci bloklarının alt türlerinden daha izleme parçalı yapı için belirtilmiş olmalı.İstemci alt türünü belirtmek için sayıyı shift sol tarafından 16 bit ve OR ile _CLIENT_BLOCK.Örne?in:

    #define MYSUBTYPE 4
    freedbg(pbData, _CLIENT_BLOCK|(MYSUBTYPE<<16));
    

    Dökme istemci bloklar halinde saklanan nesneler için bir istemci tarafından sağlanan kanca işlevi kullanılarak yüklenebilir _CrtSetDumpClientve sonra her bir istemci blok hata ayıklama işlevi tarafından dökülür çağrılacak.Ayrıca, _CrtDoForAllClientObjects hata ayıklama yığınındaki her istemci bloğu için uygulama tarafından sağlanan belirli bir işlevi çağırmak için kullanılır.

  • _FREE_BLOCK
    Normal olarak, serbest bırakılan blokları listeden kaldırılır.Bellek serbest, denetlemek için değil hala olmanın yazılır veya yetersiz bellek koşulları benzetimi yapmak için bırakılmış bloklar serbest işaretlenmiş ve bilinen bayt değeri (şu anda 0xDD) ile doldurulan bağlantılı liste tutmak seçebilirsiniz.

  • _IGNORE_BLOCK
    Bir süre için hata ayıklama yığın işlemlerini devre dışı bırakmak mümkündür.Bu sırada, bellek blokları listenizde tutulur ancak blokları yoksay olarak işaretlenir.

Türüne ve alt türüne verilen bir blok belirlemek için işlevini kullanın _CrtReportBlockType ve makroları _block_type ve _block_subtype.Makroları (crtdbg.h) aşağıdaki gibi tanımlanır:

#define _BLOCK_TYPE(block)          (block & 0xFFFF)
#define _BLOCK_SUBTYPE(block)       (block >> 16 & 0xFFFF)

Bu konuda

Yığın hata ayıklama özellikleri

Hata ayıklama öbek 's özelliklerin çoğunu gelen kodunuz içinde erişilmesi gerekir.Aşağıdaki bölümde, bazı özellikler ve bunların nasıl kullanılacağını açıklar.

  • _CrtCheckMemory
    Bir çağrı kullanabilirsiniz _CrtCheckMemory, örneğin, herhangi bir noktada öbek 's bütünlük denetimi için.Bu işlev her Öbek bellek bloğunda inceler, bellek bloğu başlığı bilgileri geçerli olduğunu doğrular ve arabellekleri değiştirilmemiş olduğunu doğrular.

  • _CrtSetDbgFlag
    Nasıl hata ayıklama yığın ayırma bir iç bayrağını kullanarak izler kontrol _crtDbgFlag, hangi okunabilir ve kullanarak _CrtSetDbgFlag işlev.Bu bayrak değiştirerek ve algılanan sızıntıları herhangi bir rapor için bellek sızıntıları çıkarken denetlemek için hata ayıklama öbek söyleyebilirsiniz.Benzer şekilde, bırakılmış belleğe bloklar düşük bellek durumlar benzetimini yapmak için bağlantılı listesinden kaldırılmaması belirtebilirsiniz.Öbek işaretlendiğinde, bunlar rahatsız verilmemiş olduğunu emin olmak için kendi bütünlükleri içerisinde bırakılmış Bu bloklar Denetlenmekte.

    _CrtDbgFlag bayrağı bit aşağıdaki alanları içerir:

    Bit alanı

    Varsayılan

    value

    Tanımlama

    _CRTDBG_ALLOC_MEM_DF

    Üzerinde

    Hata ayıklama ayırma açar.Zincirleme birlikte bu bit olduğunda kapalı, Tahsisatları kalır ancak bunların blok türü _IGNORE_BLOCK.

    _CRTDBG_DELAY_FREE_MEM_DF

    Kapalı

    Aslında, düşük bellek koşulları taklit olduğu gibi bırakılan gelen bellek engeller.Bu bit açık olduğunda, boşaltılmış blokları hata ayıklama öbek 's bağlantılı listede tutulur ancak olarak işaretli _free_block ve özel bayt değeri ile doldurulur.

    _CRTDBG_CHECK_ALWAYS_DF

    Kapalı

    Neden _CrtCheckMemory her ayırma ve ayırmayı kaldırma sırasında çağrılabilir.Bu yürütme yavaşlatır, ancak hataları hızlı bir şekilde yakalar.

    _CRTDBG_CHECK_CRT_DF

    Kapalı

    Neden türü olarak işaretlenmiş blokları _crt_block sızıntı algılaması ve durumu fark işlemlerinde dahil edilecek.Bu bit kapalıyken, çalışma zamanı kitaplığı tarafından dahili olarak kullanılan bellek gibi işlemleri sırasında göz ardı edilir.

    _CRTDBG_LEAK_CHECK_DF

    Kapalı

    Programdan çıkılırken bir çağrı yoluyla gerçekleştirilecek sızıntısı denetimi neden olan _CrtDumpMemoryLeaks.Uygulama, ayrılmış tüm belleği boşaltmak başarısız olursa bir hata raporu oluşturulur.

Bu konuda

Hata ayıklama öbek kullanma

Tüm çağrılar için yığın işlevleri gibi malloc, free, calloc, realloc, new, ve delete hata ayıklama sürümleri debug yığın içinde çalışan bu işlevlerin çözülür.Bir bellek bloğu serbest zaman hata ayıklama öbek otomatik olarak arabellekleri tahsis edilen bulunduğunuz her iki tarafındaki bütünlüğünü denetler ve üzerine oluştuysa hata raporu verir.

Hata ayıklama öbek kullanmak için

  • Uygulama hata ayıklama yapı c Çalışma Zamanı Kitaplığı'nın bir hata ayıklama sürümü ile bağlayın.

Bayrak için yeni bir durum oluşturun ve bir veya daha fazla _crtDbgFlag bit alanları değiştirmek için

  1. Call _CrtSetDbgFlag ile newFlag parametresini ayarlamak _CRTDBG_REPORT_FLAG (geçerli elde etmek için _crtDbgFlag durumu) ve döndürülen değer geçici bir değişkende depolayın.

  2. Herhangi bir BITS tarafından Aç OR- ing (Bitsel | simgesi) (uygulama kodu içinde bildirim sabitler tarafından temsil edilen) karşılık gelen şeklin ile geçici değişken.

  3. BITS tarafından devre dışı bırakma AND- ing (Bitsel & Sembol) değişkeni ile bir NOT (Bitsel ~ simgesi), uygun şeklin.

  4. Call _CrtSetDbgFlag ile newFlag parametresi ayarlanmış geçici değişkeninde saklanan değer için yeni durum oluşturmak için _crtDbgFlag.

Örneğin, aşağıdaki kod satırlarını otomatik sızıntısı algılamayı etkinleştirme ve türü için taşları denetimini devre dışı bırakmak _CRT_BLOCK:

// Get current flag
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

// Turn on leak-checking bit.
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

// Turn off CRT block checking bit.
tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;

// Set flag to the new value.
_CrtSetDbgFlag( tmpFlag );

Yeni, silme ve C++'ta _CLIENT_BLOCKs debug öbek

Hata ayıklama sürümleri c++ c Çalışma Zamanı Kitaplığı'nın hata ayıklama sürümlerini içeren new ve delete işleçleri.Kullanırsanız, _CLIENT_BLOCK tahsisat türü, hata ayıklama sürümünü çağırmanız gerekir new işleç doğrudan veya yerini makrolar oluşturmak new işleç hata ayıklama modunda, aşağıdaki örnekte gösterildiği gibi:

/* MyDbgNew.h
 Defines global operator new to allocate from
 client blocks
*/

#ifdef _DEBUG
   #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
   #define DEBUG_CLIENTBLOCK
#endif // _DEBUG


/* MyApp.cpp
        Use a default workspace for a Console Application to
 *      build a Debug version of this code
*/

#include "crtdbg.h"
#include "mydbgnew.h"

#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

int main( )   {
    char *p1;
    p1 =  new char[40];
    _CrtMemDumpAllObjectsSince( NULL );
}

Hata ayıklama sürümünü delete tüm blok işleç çalışır türleri ve bir yayım sürümünü derlediğinizde programında herhangi bir değişiklik gerektirmez.

Öbek durumu raporlama işlevleri

_CrtMemState

Belirli bir zamanda Özet bir öbek durumu görüntüsünü yakalamak için crtdbg içinde tanımlanan _CrtMemState yapısını kullanır.Y:

typedef struct _CrtMemState
{
    // Pointer to the most recently allocated block:
    struct _CrtMemBlockHeader * pBlockHeader;
    // A counter for each of the 5 types of block:
    size_t lCounts[_MAX_BLOCKS];
    // Total bytes allocated in each block type:
    size_t lSizes[_MAX_BLOCKS];
    // The most bytes allocated at a time up to now:
    size_t lHighWaterCount;
    // The total bytes allocated at present:
    size_t lTotalCount;
} _CrtMemState;

Bu yapı bir işaretçi hata ayıklama öbek 's bağlantılı liste ilk (en son ayrılmış) bloğunda kaydeder.Daha sonra iki dizide, onu ne kadar her tür bir bellek bloğu kaydeder (_normal_block, _CLIENT_BLOCK, _free_block, vb.), liste ve her tür blok içinde ayrılan bayt sayısı.Son olarak, en yüksek noktaya kadar bir bütün olarak yığın içinde ayrılan bayt sayısı ve şu anda ayrılmış bayt sayısını kaydeder.

crt Raporlama diğer işlevleri

Aşağıdaki işlevler durumu ve Öbek içeriğini rapor ve bellek sızıntıları ve diğer sorunlarının algılanmasına yardımcı olmak için bilgileri kullanın.

İşlev

Tanımlama

_CrtMemCheckpoint

Bir anlık görüntüsünü öbeğe kaydeder bir _CrtMemState uygulama tarafından sağlanan yapısı.

_CrtMemDifference

İki bellek durum yapısı karşılaştırır, üçüncü bir durum yapısı aralarındaki farkı kaydeder ve iki durumu farklı ise, doğru verir.

_CrtMemDumpStatistics

Döker bir verilen _CrtMemState yapısı.Yapısı belirli bir süre veya iki anlık görüntüler arasındaki farkı hata ayıklama öbek durumunun anlık görüntü içerebilir.

_CrtMemDumpAllObjectsSince

Öbek veya yürütme başından verilen anlık alındığından beri ayrılan tüm nesneler hakkında bilgi dökümünü alır.Onu döker her zaman bir _CLIENT_BLOCK blok, biri kullanılarak yüklenmişse, uygulama tarafından sağlanan bir kanca işlev çağırır _CrtSetDumpClient.

_CrtDumpMemoryLeaks

Herhangi bir bellek program yürütme başlangıcından bu yana oluştu sızdırıyor ve böyle bir durumda, tüm ayrılmış nesneleri döker, belirler.Her zaman _CrtDumpMemoryLeaks döker bir _CLIENT_BLOCK blok, biri kullanılarak yüklenmişse, uygulama tarafından sağlanan bir kanca işlev çağırır _CrtSetDumpClient.

Bu konuda

Yığın ayırma istekleri izleme

Kaynak dosya adı ve satır numarası yerini tam olarak belirtmekte rağmen bir assert veya raporlama makroyu çalıştırır, genellikle içinde bir sorunun nedenini bulmak için çok yararlı olduğu, aynı yığın ayırma işlevlerinin doğru değildir.Bir uygulamanın mantık ağacında birçok uygun noktalarda makroları eklenebilir, ancak bir ayırma genellikle farklı zamanlarda farklı yerlerden adı verilen özel bir yordam içinde kalmış.Soru genellikle hangi kod satırı, hatalı bir ayırma yapılan değil, ancak yerine ayırmalar binlerce birinin kod satırını tarafından yapılan hatalı ve neden oldu.

Ayırma isteği benzersiz numaralar ve _crtBreakAlloc

Hata ayıklama yığınındaki her bloğu ile ilişkili benzersiz ayırma isteği numarasını avantajlarından yararlanmak için yanlış gittiğini belirli yığın ayırma çağrı tanımlamak için en kolay yolu ise.Bu ayırma isteği sayısı, bir engelleme hakkında bilgi döküm işlevlerinden birini bildirildiğinde, küme ayraçları (örneğin, "{36}") içine alınır.

Bir hatalı ayrılan blok ayırma isteği sayısını öğrendikten sonra sizin bu numara için geçirebilirsiniz _CrtSetBreakAlloc bir kesme noktası oluşturmak için.Yürütme blok ayrılırken hemen önce kesecektir ve hangi yordamına hatalı arama için sorumlu olduğunu belirlemek için geri izleme.Yeniden önlemek için hata ayıklayıcı'daki aynı şeyi ayarlayarak gerçekleştirebilirsiniz _crtBreakAlloc ilgileniyorsanız ayırma isteği sayısı.

Hata ayıklama sürümlerini sizin ayırma düzenleri oluşturma

Kendi ayırma düzenleri, maddelerdeki hata ayıklama sürümleri oluşturmak için biraz daha karmaşık bir yaklaşım olan _dbg sürümü yığın ayırma işlevlerinin.Daha sonra kaynak dosyası ve satır arasında sayı bağımsız için temel alınan yığın ayırma düzenleri geçirebilirsiniz ve hemen kötü bir ayırma nereden geldiğini görebilirsiniz olacaktır.

Örneğin, aşağıdakine benzer bir sık kullanılan yordamı uygulamanız içerdiğini varsayalım:

int addNewRecord(struct RecStruct * prevRecord,
                 int recType, int recAccess)
{
    // ...code omitted through actual allocation... 
    if ((newRec = malloc(recSize)) == NULL)
    // ... rest of routine omitted too ... 
}

Bir üstbilgi dosyasında aşağıdaki gibi bir kod ekleyebilirsiniz:

#ifdef _DEBUG
#define  addNewRecord(p, t, a) \
            addNewRecord(p, t, a, __FILE__, __LINE__)
#endif

Ardından, ayırma, kayıt oluşturma yordamında gibi değişebilir:

int addNewRecord(struct RecStruct *prevRecord,
                int recType, int recAccess
#ifdef _DEBUG
               , const char *srcFile, int srcLine
#endif
    )
{
    /* ... code omitted through actual allocation ... */
    if ((newRec = _malloc_dbg(recSize, _NORMAL_BLOCK,
            srcFile, scrLine)) == NULL)
    /* ... rest of routine omitted too ... */
}

Artık kaynak dosyanın adı ve satır numarası nerede addNewRecord çağrıldı hata ayıklama öbeğe ayrılan her elde edilen blok içinde saklanan ve o blok incelenir, bildirdi.

Bu konuda

Ayrıca bkz.

Diğer Kaynaklar

Yerel kod hata ayıklama

crt hata ayıklama teknikleri