C/C++ hata ayıklaması için Bellek Denetleyicisi'ni genişletme

Chrome 92'de, doğrusal bellek arabelleklerini denetlemek için kullanılan bir araç olan Bellek Denetleyici'yi kullanıma sunduk. Bu makalede, C/C++ hata ayıklama için Denetleyici'yi nasıl iyileştirdiğimizi ve bu süreçte karşılaşılan teknik zorluklardan bahsedeceğiz.

C/C++ hata ayıklaması ve Bellek Denetleyicisi konularında yeniyseniz konuyla ilgili birkaç blog yayınını burada bulabilirsiniz:

Giriş

Bellek Denetleyici, doğrusal bellek arabellekleri için daha güçlü hata ayıklama seçenekleri sunar. C/C++ söz konusu olduğunda, WebAssembly belleğinde C/C++ bellek nesnelerini inceleyebilirsiniz.

Çevrenizdeki WebAssembly belleği içinde nesnenizin baytlarını tanımak bir sorun yarattı. Nesnenin boyutunu bilmeniz ve nesnenin başından itibaren baytları saymanız gerekir. Aşağıdaki ekran görüntüsünde, 10 öğeli bir int32 dizisinin ilk baytı seçilidir ancak diğer hangi baytların diziye ait olduğu hemen anlaşılmaz. Nesneye ait tüm baytları anında tanıyabilseniz ne iyi olurdu?

Orijinal bellek denetleyicisinin, tek bir baytın vurgulandığı ekran görüntüsü

Bellek Denetleyici'de nesne vurgulama

Chrome 107'den itibaren Bellek Denetleyici, bir C/C++ bellek nesnesinin tüm baytlarını vurgular. Bu, onları çevredeki bellekten ayırt etmenize yardımcı olur.

Canlı bir şekilde vurgulanan bir dizi içeren güncellenmiş bellek denetleyicisinin ekran görüntüsü

Bellek Denetleyici'nin işleyiş şeklini görmek için aşağıdaki videoyu izleyin. Bellek Denetleyicisi'nde x dizisini gösterdiğinizde, Bellek Görüntüleyici'de vurgulanmış bellek, hemen üzerinde yeni bir çiple birlikte görünür. Bu çip, vurgulanan anının adını ve türünü hatırlatır. Nesnenin belleğine atlamak için çipi tıklayın. İmleci çipin üzerine getirirseniz bir çarpı simgesi görünür. Vurguyu kaldırmak için üzerine tıklayın.

İncelediğiniz nesnenin dışında bir bayt seçtiğinizde, vurgu, dikkatinizin dağılmasını önlemek için odaklama yapar. Yeniden odaklamak için nesnenin baytlarından birini veya çipi tekrar tıklayın.

Nesne vurgulama desteği dizilerle sınırlı değildir. Yapıları, nesneleri ve işaretçileri de inceleyebilirsiniz. Bu değişiklikler, C/C++ uygulamalarınızın belleğini keşfetmeyi hiç olmadığı kadar kolaylaştırıyor.

Denemek ister misiniz? Yapmanız gerekenler:

  • Chrome 107 veya sonraki bir sürümün yüklü olması gerekir.
  • C/C++ DWARF uzantısını yükleyin.
  • Geliştirici Araçları > Ayarlar'a dokunun. Ayarlar > Deneysel > WebAssemble Hata Ayıklama: DWARF desteğini etkinleştir'i seçerek DWARF hata ayıklama özelliğini etkinleştirin.
  • Bu demo sayfasını açın.
  • Sayfadaki talimatları uygulayın.

Hata ayıklama örneği

Bu bölümde, C/C++ hata ayıklaması için Bellek Denetleyicisi'ni nasıl kullanabileceğinizi göstermek üzere oyuncak bir hataya bakalım. Aşağıdaki kod örneğinde, bir programcı bir tam sayı dizisi oluşturur ve son öğeyi seçmek için işaretçi aritmetiği kullanmaya karar verir. Maalesef programcı, işaretçi hesaplamasında hata yaptı ve program artık son öğeyi yazdırmak yerine anlamsız değerler yazdırıyor.

#include <iostream>

int main()
{
    int numbers[] = {1, 2, 3, 4};
    int *ptr = numbers;
    int arraySize = sizeof(numbers)/sizeof(int);
    int* lastNumber = ptr + arraySize;  // Can you notice the bug here?
    std::cout <<../ *lastNumber <<../ '\n';
    return 0;
}

Programcı, sorundaki hataları ayıklamak için Bellek Denetleyicisi'ne döner. Bu demo ile birlikte işlem yapabilirsiniz. İlk olarak Bellek Denetleyici'de diziyi inceler ve numbers dizisinin beklendiği gibi yalnızca 1, 2, 3 ve 4 tam sayılarını içerdiğini görür.

İncelenen bir int32 dizisiyle açık bellek denetleyicisinin ekran görüntüsü. Tüm dizi öğeleri vurgulanır.

Ardından, Kapsam bölmesinde lastNumber değişkenini gösterir ve işaretçinin dizi dışındaki bir tam sayıya işaret ettiğini fark eder. Bu bilgiye sahip olan programcı, 8. satırdaki işaretçi ofsetini yanlış saydığını fark eder. ptr + arraySize - 1 olmalıdır.

&quot;lastNumber&quot; adlı bir işaretçi tarafından işaretlenen vurgulanmış belleği gösteren, açık bellek denetleyicisinin ekran görüntüsü. Vurgulanan bellek, daha önce vurgulanmış dizinin son baytından hemen sonra yer alır.

Bu örnek basit olsa da nesne vurgulamanın, bellek nesnelerinin boyutunu ve konumunu etkili bir şekilde nasıl aktardığını gösterir. Bu da C/C++ uygulamanızın belleğinde neler olduğunu daha iyi anlamanıza yardımcı olabilir.

Geliştirici Araçları'nın vurgulananları nasıl belirlediği

Bu bölümde, C/C++ hata ayıklama özelliğini sunan araç ekosistemine göz atacağız. Daha ayrıntılı olarak belirtmek gerekirse DevTools, V8, C/C++ DWARF uzantısı ve Emscripten'in Chrome'da C/C++ hata ayıklama özelliğini nasıl sağladığını öğreneceksiniz.

Geliştirici Araçları&#39;nda C/C++ hata ayıklama özelliğinin tüm gücünden yararlanmak için iki şeye ihtiyacınız vardır:

  • Chrome'a yüklenen C/C++ DWARF uzantısı
  • Bu blog yayınındaki talimatlara göre en son Emscripten derleyiciyle WebAssembly'e derlenmiş C/C++ kaynak dosyaları

Peki neden? Chrome'un JavaScript ve WebAssembly motoru olan V8, C veya C++ 'nin nasıl çalıştırılacağını bilmez. C/C++ to WebAssembly derleyicisi Emscripten sayesinde, C veya C++ ürününde C veya C++'ta WebAssembly olarak yerleşik uygulamaları derleyebilir ve tarayıcıda yürütebilirsiniz.

emscripten, derleme sırasında DWARF hata ayıklama verilerini ikili dosyanıza yerleştirir. Bu veriler, genel hatlarıyla uzantının C/C++ değişkenlerinize hangi WebAssembly değişkenlerinin karşılık geldiğini ve daha fazlasını belirlemesine yardımcı olur. Bu sayede DevTools, V8'in aslında WebAssembly çalıştırmasına rağmen C++ değişkenlerinizi size gösterebilir. DWARF hata ayıklama verileri örneği görmek istiyorsanız bu blog yayınına göz atın.

lastNumber'yi gösterdiğinizde ne olur? Bellek simgesini tıkladığınızda DevTools, incelemek istediğiniz değişkeni kontrol eder. Ardından, lastNumber veri türü ve konumu hakkında uzantıyı sorgulanır. Uzantı bu bilgilerle yanıt verir vermez Bellek Denetleyici ilgili bellek dilimini görüntüleyebilir ve türünü bilerek nesnenin boyutunu da gösterebilir.

Önceki örnekteki lastNumber'e bakarsanız lastNumber: int *'ü incelediğimizi ancak Bellek Denetleyici'deki çipin *lastNumber: int olduğunu görebilirsiniz. Bu durum neden kaynaklanıyor? İnceleyici, size gösterilen nesnenin türünü belirtmek için C++ tarzı işaretçi referans almayı kullanır. Bir işaretçiyi incelediğinizde işaretçinin neyi gösterdiğini görebilirsiniz.

Hata ayıklayıcı adımlarında öne çıkan noktalar

Bellek Denetleyicisi'nde bir nesne gösterdiğinizde ve hata ayıklayıcıyla birlikte adım bırakıldığında Denetleyici, hâlâ geçerli olduğunu düşünüyorsa vurgulamayı sürdürür. Başlangıçta bu özelliği yol haritamızda yoktu ancak bu durumun hata ayıklama deneyiminizi olumsuz etkilediğini kısa sürede fark ettik. Aşağıdaki videoda olduğu gibi her adımdan sonra diziyi yeniden incelemeniz gerektiğini düşünün.

Hata ayıklayıcı yeni bir kesme noktasına ulaştığında Bellek Denetleyicisi, V8'i ve önceki vurgulamayla ilişkili değişkenin uzantısını tekrar sorgular. Ardından nesnelerin konumlarını ve türlerini karşılaştırır. Eşleşiyorlarsa vurgu devam eder. Yukarıdaki videoda, x dizisine yazan bir for döngüsü vardır. Bu işlemler, dizinin türünü veya konumunu değiştirmediğinden dizi vurgulu kalır.

Bunun işaretçileri nasıl etkilediğini merak edebilirsiniz. Vurgulanmış bir işaretçiniz varsa ve onu farklı bir nesneye yeniden atarsanız, vurgulanan nesnelerin eski ve yeni konumları farklılık gösterir ve vurgu kaybolur. Yeni işaret edilen nesne WebAssembly Belleğinde herhangi bir yerde bulunabileceğinden ve önceki bellek konumuna göre muhtemelen çok az olacağı için vurguyu kaldırmak, yeni bir bellek konumuna atlamaktan daha nettir. Kapsam bölmesindeki bellek simgesini tıklayarak işaretçiyi tekrar vurgulayabilirsiniz.

Sonuç

Bu makalede, C/C++ hata ayıklama için Bellek Denetleyici'de yaptığımız iyileştirmeler açıklanıyordu. Yeni özelliklerin C/C++ uygulamalarınızın belleğinde hata ayıklama işlemini basitleştireceğini umuyoruz. Daha da iyileştirme önerileriniz varsa hata bildirerek bize bildirin.

Sırada ne var?

Daha fazla bilgi için: