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 zorlukları ele alacağız.
C/C++ hata ayıklama ve Bellek Denetleyici'ye yeni başladıysanız aşağıdaki alakalı blog yayınlarını inceleyebilirsiniz:
- Derin bellek hata ayıklama ile ilgileniyor musunuz? Bellek Denetleyicisi'ni tanıtıyoruz başlıklı makaleyi inceleyin.
- C/C++ hata ayıklama araçlarının tamamına giriş yapmak ister misiniz? Modern araçlarla WASM'de hata ayıklama ve WebAssembly'de daha hızlı hata ayıklama başlıklı makaleleri inceleyin.
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çilidir ancak diğer baytların hangilerine ait olduğu hemen anlaşılmaz. Nesneye ait tüm baytları anında tanıyabilseniz ne iyi olurdu?
Bellek Denetleyicisi'nde 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.
Bellek Denetleyici'nin işleyiş şeklini 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 belleğine 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.
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 > 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ıklama için Bellek Denetleyici'yi nasıl kullanabileceğinizi açıklamak amacıyla bir oyuncak hataya göz atalı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ı, sorunu gidermek için Bellek Denetleyici'ye başvurur. Bu demo ile süreci 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.
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.
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ı'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++'yi nasıl çalıştıracağını bilmez. C/C++'den WebAssembly'e derleyici olan Emscripten sayesinde, C veya C++'de oluşturulan uygulamaları WebAssembly olarak derleyebilir ve tarayıcıda çalıştırabilirsiniz.
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 çıkanları koruma
Bellek Denetleyicisi'nde bir nesneyi gösterdiğinizde ve hata ayıklayıcıyla adım attığınızda Denetleyici, hâlâ geçerli olduğunu düşünürse vurgulamayı korur. 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 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ş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 bunu farklı bir nesneye yeniden atarsanız vurgulanmış nesnelerin eski ve yeni konumları farklı olur ve vurgu kaybolur. Yeni işaretlenen nesne WebAssembly belleğinin herhangi bir yerinde bulunabileceğinden ve önceki bellek konumuyla muhtemelen çok az ilişkisi olacağından, 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ı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ıklamayı kolaylaştıracağını umuyoruz. Daha da iyileştirmemiz için önerileriniz varsa hata bildirerek bize bildirin.
Sırada ne var?
Daha fazla bilgi için: