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

Chrome 92'de, doğrusal bellek arabelleklerini denetlemek için kullanılan Bellek Denetleyici'yi kullanıma sunduk. Bu makalede, C/C++ hata ayıklaması için Denetleyici'yi nasıl geliştirdiğimizi ve bu süreçte karşılaşılan teknik zorlukları açıklayacağız.

C/C++ hata ayıklaması ve Bellek Denetleyicisi konularında yeniyseniz konuyla ilgili birkaç blog yayınından bazılarını aşağıda 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.

Nesnenizin baytlarını çevreleyen WebAssembly belleği arasında tanımak sorundu. Nesnenin boyutunu bilmeniz ve nesnenin başlangıcından itibaren baytları saymanız gerekir. Aşağıdaki ekran görüntüsünde, 10 öğeli bir int32 dizisinin ilk baytı seçilmiş ancak başka hangi baytların diziye ait olduğu hemen anlaşılmamaktadır. 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 Denetleyicisi, bir C/C++ bellek nesnesinin tüm baytlarını vurgular. Bu, onları etraftaki anıdan ayırt etmenize yardımcı olur.

Canlı olarak vurgulanmış bir diziyi içeren güncellenmiş bellek denetleyicisinin ekran görüntüsü

Bellek Denetleyicisi'nin nasıl çalıştığını görmek için aşağıdaki videoyu izleyin. Bellek Denetleyicisi'nde x dizisini gösterdiğinizde, vurgulanan bellek Bellek Görüntüleyici'de gösterilir ve hemen üstünde yeni bir çip görünür. Bu çip, vurgulanan belleğin adını ve türünü hatırlatır. Nesnenin hafızasına atlamak için çipi tıklayın. Fareyle çipin üzerine geldiğinizde bir çarpı simgesi görünür. Vurgulanan öğeyi kaldırmak için bu simgeyi tıklayın.

İncelediğiniz nesnenin dışında bir bayt seçtiğinizde dikkatinizin dağılmasını önlemek için vurgunun odak noktası kaldırılır. Yeniden odaklamak için nesnenin baytlarından birini veya çipi tekrar tıklayın.

bulabilirsiniz.

Nesne vurgulama desteği dizilerle sınırlı değildir. struct'ları, nesneleri ve işaretçileri de inceleyebilirsiniz. Bu değişiklikler, C/C++ uygulamalarınızın belleğini keşfetmeyi her zamankinden daha kolay hale getiriyor.

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ı, sorunda hata ayıklama yapmak için Bellek Denetleyici'ye başvurur. Bu demoyu takip edebilirsiniz. İ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 dizisi içeren açık bellek denetleyicisinin ekran görüntüsü. Tüm dizi öğeleri vurgulanır.

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

&quot;lastNumber&quot; adlı bir işaretçiyle vurgulanan belleği gösteren, açılan bellek denetleyicisinin ekran görüntüsü. Vurgulanan bellek, daha önce vurgulanan dizinin son baytından hemen sonradır.

Bu, oyuncak bir örnek olsa da nesne vurgulamanın, bellek nesnelerinin boyutunu ve konumunu nasıl etkili bir şekilde aktardığını ve bu da C/C++ uygulamanızın belleğinde neler olup bittiğini 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ıklamasını etkinleştiren 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ı'nda C/C++ hata ayıklama özelliğinin tüm gücünden yararlanmak için iki şeye ihtiyacınız vardır:

  • Chrome'da yüklü C/C++ DWARF uzantısı
  • Bu blog yayınında açıklandığı şekilde, en son Emscripten derleyicisiyle WebAssembly'de derlenen C/C++ kaynak dosyaları

Peki neden? Chrome'un JavaScript ve WebAssembly motoru olan V8, C veya C++'ın nasıl yürütüleceğini bilmez. C/C++ to WebAssembly derleyicisi olan Emscripten sayesinde, C veya C++'ta yerleşik olarak bulunan uygulamaları WebAssembly olarak 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 şekilde, V8 aslında WebAssembly çalıştırmasına rağmen Geliştirici Araçları size C++ değişkenlerinizi gösterebilir. Merak ediyorsanız DWARF hata ayıklama verisi örneği için bu blog yayınına göz atabilirsiniz.

Peki, lastNumber öğesini gösterdiğinizde tam olarak ne oluyor? 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 incelerseniz denetleyici, işaretçinin neye işaret ettiğini size gösterir.

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

Bellek Denetleyicisi'nde bir nesne gösterdiğinizde ve hata ayıklayıcıyla adım bırakıldığında Denetleyici, hâlâ geçerli olduğunu düşünüyorsa vurgulamayı sürdürür. Başlangıçta, yol haritamızda bu özellik yoktu. Ancak bunun hata ayıklama deneyiminizi tehlikeye attığını hemen fark ettik. Aşağıdaki videoda olduğu gibi her adımdan sonra diziyi yeniden incelemek zorunda kaldığınızı düşünün.

Hata ayıklayıcı yeni bir kesme noktasına ulaştığında Hafıza Denetleyici, önceki vurgulamayla ilişkili değişken için V8'i ve uzantıyı tekrar sorgular. Ardından nesnelerin konumlarını ve türlerini karşılaştırır. Eşleşmelerse vurgulama 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ştirmez, bu nedenle vurgulanmış halde kalır.

Bunun işaretçileri nasıl etkilediğini merak edebilirsiniz. Vurgulanmış bir işaretçiniz varsa ve bunu farklı bir nesneye yeniden atarsanız vurgulanmış nesnelerin eski ve yeni konumları farklı olur 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ölmesinde yer alan bellek simgesini tıklayarak işaretçiyi tekrar vurgulayabilirsiniz.

Sonuç

Bu makalede, C/C++ hata ayıklaması için Bellek Denetleyicisi'nde yaptığımız iyileştirmeler açıklanmaktadır. Yeni özelliklerin, C/C++ uygulamalarınızın belleğinde hata ayıklamayı kolaylaştıracağını umuyoruz. Daha fazla iyileştirmeyle ilgili önerileriniz varsa hata bildiriminde bulunarak bize bildirin.

Sırada ne var?

Daha fazla bilgi için: