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

Chrome 92'de, doğrusal bellek arabelleklerini incelemeye yarayan bir araç olan Bellek Denetleyicisi'ni kullanıma sunduk. Bu makalede, C/C++ hata ayıklaması için denetçiyi nasıl geliştirdiğimizi ve süreç boyunca karşılaşılan teknik zorlukları ele alacağız.

C/C++ hata ayıklaması ve Bellek Denetleyicisi konularında yeniyseniz, konuyla ilgili birkaç blog yayını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 sorun teşkil ediyordu. Nesnenin boyutunu bilmeniz ve baytları nesnenin başından itibaren saymanız gerekir. Aşağıdaki ekran görüntüsünde 10 öğeli bir int32 dizisinin ilk baytı seçilmiştir. Ancak diğer hangi baytların diziye ait olduğu hemen net olarak anlaşılmaz. Nesneye ait tüm baytları anında tanıyabilseydiniz güzel olmaz mıydı?

Vurgulanan tek bir baytın yer aldığı orijinal bellek denetleyicisinin ekran görüntüsü

Bellek Denetleyicisi'nde nesne vurgulama

Bellek Denetleyici, Chrome 107 sürümünden itibaren C/C++ bellek nesnesinin tüm baytlarını vurgular. Bu, onları diğer hafızalardan ayırt etmenize yardımcı olur.

Canlı bir şekilde vurgulanan bir diziye sahip güncellenmiş bellek denetleyicisinin ekran görüntüsü

Bellek Denetleyicisi'ni çalışırken görmek için aşağıdaki videoyu izleyin. Bellek Denetleyicisi'nde x dizisini gösterdiğinizde, vurgulanan bellek hemen üzerinde yeni bir çiple birlikte Bellek Görüntüleyici'de görünür. Bu çip, vurgulanan anın adını ve türünü hatırlatır. Nesnenin belleğine gitmek için çipi tıklayın. İmleci çipin üzerine getirdiğinizde çapraz simge görünür. Vurguyu 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 odağı kaybolur. Tekrar odaklamak için nesnenin baytlarından birini veya çipi tekrar tıklayın.

Nesne vurgulama desteği dizilerle sınırlı değildir. Ayrıca yapı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 getirir!

Denemek ister misin? Yapmanız gerekenler:

  • Chrome 107 veya daha yeni bir sürüm kullanıyorsanız.
  • C/C++ DWARF uzantısını yükleyin.
  • DevTools > Ayarlar. DevTools > DevTools > DevTools bölümünde DWARF hata ayıklamasını 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 bir oyuncak hataya göz atalım. Aşağıdaki kod örneğinde, bir programcı bir tamsayı dizisi oluşturur ve son öğeyi seçmek için işaretçi aritmetiğini kullanmaya karar verir. Ne yazık ki programcı, işaretçi hesaplamasında bir hata yaptı ve şimdi 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ı, sorunun hatalarını ayıklamak için Bellek Denetleyicisi'ne başvurur. Bu demoyu takip edebilirsiniz. İlk olarak diziyi Bellek Denetleyicisi'nde inceler ve numbers dizisinin beklendiği gibi yalnızca 1, 2, 3 ve 4 tam sayılarını içerdiğini görürler.

İncelenmiş bir int32 dizisine sahip açık bellek denetleyicisinin ekran görüntüsü. Tüm dizi öğeleri vurgulanmıştır.

Daha sonra, Kapsam bölmesinden lastNumber değişkenini açığa çıkarıyor ve işaretçinin, dizinin dışındaki bir tam sayıyı gösterdiğine dikkat ediyor. Bu bilgiye sahip olan programcı, 8. satırda işaretçi ofseti yanlış saydığını fark eder. ptr + arraySize - 1 olmalıydı.

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

Bu, bir oyuncak örneği olsa da, nesne vurgulamanın bellek nesnelerinin boyutunu ve konumunu etkili bir şekilde nasıl aktardığını ve bu da C/C++ uygulamanızın belleğinde neler olup bittiğini daha iyi anlamanıza yardımcı olabildiğini göstermektedir.

Geliştirici Araçları nelerin vurgulanacağını nasıl anlar?

Bu bölümde, C/C++ hata ayıklamasını sağlayan araç ekosistemini inceleyeceğiz. Özel olarak, Geliştirici Araçları, V8, C/C++ DWARF Uzantısı ve Emscripten'in, Chrome'da C/C++ hata ayıklamasını nasıl mümkün hale getirdiğini öğreneceksiniz.

Geliştirici Araçları'nda C/C++ hata ayıklamasının 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ığı gibi, en son Emscripten derleyicisiyle WebAssembly'de derlenen C/C++ kaynak dosyaları

Ama neden? Chrome'un JavaScript ve WebAssembly motoru V8, C veya C++'yı nasıl çalıştıracağını bilmez. C/C++'dan WebAssembly'ye derleyici olan Emscripten sayesinde C veya C++'da oluşturulan uygulamaları WebAssembly olarak derleyebilir ve tarayıcıda çalıştırabilirsiniz.

Derleme sırasında emscripten, DWARF hata ayıklama verilerini ikili dosyanıza yerleştirir. Genel olarak bu veriler, uzantının hangi WebAssembly değişkenlerinin C/C++ değişkenlerinize karşılık geldiğini ve daha fazlasını belirlemesine yardımcı olur. Bu şekilde, V8 aslında WebAssembly'yi çalıştırmasına rağmen Geliştirici Araçları, C++ değişkenlerinizi gösterebilir. Merak ediyorsanız DWARF hata ayıklama verilerinin bir örneği için bu blog yayınına göz atın.

Peki lastNumber özelliğini açtığınızda aslında ne oluyor? Bellek simgesini tıkladığınızda Geliştirici Araçları, incelemek istediğiniz değişkeni kontrol eder. Ardından, uzantıyı lastNumber veri türü ve konumuyla ilgili sorgular. Uzantı, bu bilgilerle yanıt verir vermez Bellek Denetleyici, ilgili bellek dilimini görüntüleyebilir ve türünü öğrenerek size nesnenin boyutunu da gösterebilir.

Önceki örnekteki lastNumber öğesine bakarsanız lastNumber: int * öğesini incelediğimizi fark edebilirsiniz. Ancak Bellek Denetleyicisi'ndeki çipte *lastNumber: int yazıyor. Bu değer ne anlama gelir? İnceleyici, size gösterilen nesnenin türünü belirtmek için C++ stilinde işaretçi referans alma kullanır. İşaretçiyi denetliyorsanız, denetleyici size onun neye işaret ettiğini gösterir.

Hata ayıklayıcı adımlarında vurgulanan noktaların kalıcı olması

Bellek Denetleyicisi'nde bir nesneyi ortaya çıkarıp hata ayıklayıcıyla birlikte bir adım attığınızda Denetleyici hâlâ geçerli olduğunu düşünüyorsa vurguyu devam ettirir. Başlangıçta bu özellik yol haritamızda yoktu, ancak kısa sürede bu durumun hata ayıklama deneyiminizi tehlikeye atacağını fark ettik. Aşağıdaki videoda olduğu gibi, diziyi her adımdan sonra yeniden incelemek zorunda olduğunuzu düşünün.

Hata ayıklayıcı yeni bir ayrılma noktasına ulaştığında Bellek İnceleyici, önceki vurguyla ilişkilendirilen değişkenin uzantısını tekrar ve V8'i sorgular. Ardından, nesnelerin konumlarını ve türlerini karşılaştırır. Eşleşiyorlarsa vurgulama devam eder. Yukarıdaki videoda x dizisine bir for-loop yazma işlemi gösterilmektedir. Bu işlemler, dizinin türünü veya konumunu değiştirmez, böylece dizi vurgulanmış olarak kalır.

Bunun işaretçileri nasıl etkilediğini merak ediyor olabilirsiniz. Vurgulanmış bir işaretçiniz varsa ve bunu 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ği'nde herhangi bir yerde bulunabileceğinden ve muhtemelen önceki bellek konumuyla pek az ilgisi olacağından, vurgunun kaldırılması, yeni bir bellek konumuna atlamaktan daha nettir. İşaretçiyi, Kapsam bölmesinde bellek simgesini tıklayarak tekrar vurgulayabilirsiniz.

Sonuç

Bu makalede, C/C++ hata ayıklaması için Bellek Denetleyicisi'nde yaptığımız iyileştirmeler açıklandı. Yeni özelliklerin, C/C++ uygulamalarınızın belleğinde hata ayıklamayı kolaylaştıracağını umuyoruz. Özelliği daha fazla iyileştirmeye yönelik önerileriniz varsa hata bildiriminde bulunarak bize bildirin!

Sonraki adımlar

Daha fazla bilgi edinmek için aşağıdaki makaleleri inceleyin: