Geldiğimiz nokta
Chrome, bir yıl önce Chrome Geliştirici Araçları'nda yerel WebAssembly hata ayıklama için ilk desteği duyurmuştu.
Temel adım desteğini gösterdik ve kaynak haritalar yerine DWARF bilgilerinin kullanımının gelecekte bize sunacağı fırsatlardan bahsettik:
- Değişken adlarını çözme
- Okunaklı hale getirme türleri
- Kaynak dillerdeki ifadeleri değerlendirme
- …ve daha fazlası!
Bugün, vadettiğimiz özelliklerin hayata geçtiğini göstermekten heyecan duyuyoruz. Emscripten ve Chrome Geliştirici Araçları ekiplerinin C ve C++ uygulamaları için büyük bir fırsat oluşturuyor.
Başlamadan önce, bunun yeni deneyimin beta sürümünün hâlâ olduğunu, tüm araçların en son sürümünü kendi sorumluluğunuzda kullanmanız gerektiğini ve herhangi bir sorunla karşılaşırsanız lütfen https://issues.chromium.org/issues/new?noWizard=true&template=0&component=1456350 adresinden bildirin.
Geçen seferkiyle aynı basit C örneğiyle başlayalım:
#include <stdlib.h>
void assert_less(int x, int y) {
if (x >= y) {
abort();
}
}
int main() {
assert_less(10, 20);
assert_less(30, 20);
}
Derlemek için en son Emscripten'i kullanırız ve hata ayıklama bilgilerini dahil etmek üzere orijinal gönderide olduğu gibi bir -g
işareti iletiriz:
emcc -g temp.c -o temp.html
Artık oluşturulan sayfayı bir localhost HTTP sunucusundan ( örneğin, serve) ve en son Chrome Canary'de açmanız gerekir.
Bu kez, Chrome DevTools ile entegre olan ve WebAssembly dosyasında kodlanmış tüm hata ayıklama bilgilerini anlamasına yardımcı olan bir yardımcı uzantıya da ihtiyacımız var. Lütfen şu bağlantıya giderek yükleyin: goo.gle/wasm-debugging-extension
DevTools Denemeler bölümünde WebAssembly hata ayıklama özelliğini de etkinleştirmeniz gerekir. Chrome Geliştirici Araçları'nı açın, DevTools bölmesinin sağ üst köşesindeki dişli (⚙) simgesini tıklayın, Deneysel paneline gidin ve WebAssembly Hata Ayıklama: DWARF desteğini etkinleştir'i işaretleyin.
Ayarlar'ı kapattığınızda Geliştirici Araçları, ayarları uygulamak için kendisini yeniden yüklemeyi önerir. Biz de bunu yapalım. Tek seferlik kurulum bu kadar.
Şimdi Kaynaklar paneline geri dönebilir, İstisnalarda duraklat'ı (⏸ simgesi) etkinleştirebilir, ardından Tespit edilen istisnalarda duraklat'ı işaretleyip sayfayı yeniden yükleyebiliriz. Geliştirici Araçları'nın bir istisnada duraklatıldığını göreceksiniz:
Varsayılan olarak, Emscripten tarafından oluşturulan bir yapıştırma kodunda durur ancak sağ tarafta hatanın yığın izlemesini temsil eden bir Çağrı Yığını görünümü görebilirsiniz ve abort
'yi çağıran orijinal C satırına gidebilirsiniz:
Artık Kapsam görünümüne baktığınızda orijinal adların
ve değerlerini C/C++ kodundaki değişkenlerin değerleri ile ilişkilendirir ve artık
$localN
gibi karışık isimlerin ne anlama geldiğini ve
kaynak kodundan kaynaklanabilir.
Bu durum yalnızca tam sayılar gibi ilkel değerler için değil, yapı, sınıf, dizi vb. gibi karmaşık türler için de geçerlidir.
Zengin tür desteği
Bunları göstermek için daha karmaşık bir örneğe bakalım. Bu kez aşağıdaki C++ koduyla bir Mandelbrot fraktalı çizeceğiz:
#include <SDL2/SDL.h>
#include <complex>
int main() {
// Init SDL.
int width = 600, height = 600;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window;
SDL_Renderer* renderer;
SDL_CreateWindowAndRenderer(width, height, SDL_WINDOW_OPENGL, &window,
&renderer);
// Generate a palette with random colors.
enum { MAX_ITER_COUNT = 256 };
SDL_Color palette[MAX_ITER_COUNT];
srand(time(0));
for (int i = 0; i < MAX_ITER_COUNT; ++i) {
palette[i] = {
.r = (uint8_t)rand(),
.g = (uint8_t)rand(),
.b = (uint8_t)rand(),
.a = 255,
};
}
// Calculate and draw the Mandelbrot set.
std::complex<double> center(0.5, 0.5);
double scale = 4.0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
std::complex<double> point((double)x / width, (double)y / height);
std::complex<double> c = (point - center) * scale;
std::complex<double> z(0, 0);
int i = 0;
for (; i < MAX_ITER_COUNT - 1; i++) {
z = z * z + c;
if (abs(z) > 2.0)
break;
}
SDL_Color color = palette[i];
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderDrawPoint(renderer, x, y);
}
}
// Render everything we've drawn to the canvas.
SDL_RenderPresent(renderer);
// SDL_Quit();
}
Gördüğünüz gibi bu uygulama da oldukça küçük. Uygulama, 50 satır kod içeren bir dosya ama bu defa ben de için SDL kitaplığı gibi harici API'ler karmaşık sayılar ve bunların C++ standart kitaplığı.
Dahil etmek için yukarıdakiyle aynı -g
işaretiyle derleyeceğim.
hata ayıklama bilgilerini aktaracağım. Ayrıca, Emscripten'den SDL2
kitaplığını açabilir ve rastgele boyutlandırılmış belleğe izin verebilirsiniz:
emcc -g mandelbrot.cc -o mandelbrot.html \ -s USE_SDL=2 \ -s ALLOW_MEMORY_GROWTH=1
Oluşturulan sayfayı tarayıcıda ziyaret ettiğimde, rastgele renklerle güzel bir fraktalı şekil görüyorum:
Geliştirici Araçları'nı açtığımda tekrar orijinal C++ dosyasını görüyorum. Bu ancak kodda herhangi bir hata yok (üe!). Bu nedenle, kodumuzun başına koyabileceğimiz yeni bir
Sayfayı tekrar yüklediğimizde hata ayıklayıcı, C++ kaynağımızın tam içinde duraklar:
Tüm değişkenlerimizi sağ tarafta görebiliriz ancak şu anda yalnızca width
ve height
başlatılmıştır. Bu nedenle, incelenecek çok fazla şey yoktur.
Ana Mandelbrot döngümüze başka bir ayrılma noktası ekleyip ileri sarabilirim.
Bu noktada palette
aracımız rastgele renklerle dolduruldu.
hem dizinin kendisini hem de
şunları doğrulamak için SDL_Color
yapıyı ve bileşenlerini inceleyin
her şey yolunda görünüyor (örneğin, "alfa" kanalı
tam opaklığa). Benzer şekilde, mevcut müşteri tabanının
center
değişkeninde depolanan karmaşık sayının sanal bölümleri.
Kapsam görünümü aracılığıyla erişmesi zor olan, derin iç içe yerleştirilmiş bir mülke erişmek istiyorsanız Console değerlendirmesini de kullanabilirsiniz. Ancak daha karmaşık C++ ifadelerinin henüz desteklenmediğini unutmayın.
Yürütmeye birkaç kez devam edelim ve iç x
öğesinin nasıl olduğunu
Kapsam görünümüne tekrar bakarak, yeni bir kitle eklemek için
bunu izleme listesine ekleyerek, konsolda değerlendirerek veya
kaynak koddaki değişkenin üzerine gelin:
Buradan, C++ ifadelerini devreye alabilir veya bunların nasıl diğer değişkenler de değişiyor:
Hata ayıklama bilgileri mevcut olduğunda bu yöntemler mükemmel şekilde çalışır. Peki hata ayıklama seçenekleriyle derlenmemiş bir kodda hata ayıklama yapmak istersek ne olur?
Ham WebAssembly hata ayıklama
Örneğin, Emscripten'den her örnek için önceden oluşturulmuş bir SDL kitaplığı
kaynağından kendimiz derlemek yerine, en azından
Şu anda hata ayıklayıcının ilişkili kaynakları bulması mümkün değildir.
SDL_RenderDrawColor
devreye girelim:
Ham WebAssembly hata ayıklama deneyimine geri döndük.
Çok korkutucu görünüyor ve çoğu Web geliştiricisinin isteyeceği bir şey değil, zaman zaman bir hata ayıklamanız gerekebilir, ancak veya hata ayıklama bilgileri içermeyen bir kitaplık Kontrolün sizde olmadığı 3. taraf kitaplığı veya yalnızca üretimde oluşan hatalardan biriyle karşılaşabilirsiniz.
Bu durumlarda yardımcı olmak için, Okuyucu Gelirleri Yöneticisi'nin hata ayıklama deneyiminden yararlanabilirsiniz.
Öncelikle, daha önce ham WebAssembly hata ayıklama özelliğini kullandıysanız artık tüm kod ayrıştırmasının tek bir dosyada gösterildiğini fark edebilirsiniz. Artık wasm-53834e3e/
wasm-53834e3e-7
Kaynaklar girişinin hangi işleve karşılık geldiğini tahmin etmeniz gerekmez.
Yeni ad oluşturma şeması
Demonte görünümündeki adları da iyileştirdik. Daha önce yalnızca sayısal dizinler veya işlevler söz konusu olduğunda hiç ad gösterilmiyordu.
Artık WebAssembly ad bölümündeki ipuçlarını, içe/dışa aktarma yollarını kullanarak ve diğer tüm yöntemler başarısız olursa $func123
gibi öğenin türüne ve dizine göre adları diğer disassemblör araçlarına benzer şekilde oluşturuyoruz. Şunları yapabilirsiniz:
yukarıdaki ekran görüntüsünde, bu yöntemin biraz da
daha okunabilir yığın izlemeleri
ve parçalarına ayırmaya yardımcı olur.
Tür bilgisi olmadığında, ilkellerin dışındaki değerleri incelemek zor olabilir. Örneğin, işaretçiler normal tam sayılar olarak gösterilir ve bellekte arkalarında nelerin depolandığını bilmek mümkün olmaz.
Bellek denetimi
Daha önce, yalnızca Kapsam görünümünde env.memory
ile gösterilen WebAssembly bellek nesnesini genişletebiliyordunuz.
kullanılabilir. Bu yöntem bazı basit senaryolarda işe yaradı ancak
ve verilerin yeniden yorumlanmasına izin vermemek, özellikle
farklı biçimlerde olabilir. Bu konuda size yardımcı olacak yeni bir özellik de ekledik: doğrusal bellek denetleyicisi.
env.memory
öğesini sağ tıklarsanız artık yeni bir
Belleği incele adlı seçeneği görebilirsiniz:
Tıklandığında, WebAssembly belleğini onaltılık ve ASCII görünümlerinde inceleyebileceğiniz, belirli adreslere gidebileceğiniz ve verileri farklı biçimlerde yorumlayabileceğiniz bir Bellek Denetleyicisi açılır:
Gelişmiş senaryolar ve uyarılar
WebAssembly kodunda profil oluşturma
Geliştirici Araçları'nı açtığınızda WebAssembly kodu, hata ayıklama özelliğini etkinleştirmek için optimize edilmemiş bir sürüme "indirilir". Bu sürüm çok daha yavaş.
Bu da console.time
, performance.now
özelliklerine güvenemeyeceğiniz anlamına gelir.
ve diğer yöntemler de kodsuz olduğunda
elde ettiğiniz sayılar gerçek dünya performansını temsil etmediğinden,
mümkün değil.
Bunun yerine Geliştirici Araçları Performans panelini kullanmalısınız. Bu da kodu tam hızda çalıştırır ve size bir farklı fonksiyonlarda harcanan zamanın ayrıntılı dökümü:
Alternatif olarak, uygulamanızı Geliştirici Araçları kapalıyken çalıştırabilir ve Konsol'u incelemek için işlem tamamlandıktan sonra Geliştirici Araçları'nı açabilirsiniz.
Gelecekte profil çıkarma senaryolarını geliştireceğiz, ancak şimdilik bir dikkat etmeniz gerekir. WebAssembly hakkında daha fazla bilgi edinmek isterseniz WebAssembly derleme ardışık düzeni ile ilgili dokümanlarımıza göz atın.
Farklı makinelerde (Docker/ana makine dahil) derleme ve hata ayıklama
Docker, sanal makine veya uzak derleme sunucusunda derleme yaparken kaynak dosyalara giden yolların belirli bir süre içinde oluşturma sırasında kullanılan yolların, kendi dosya sisteminizdeki çalıştığını fark edebilirsiniz. Bu durumda, dosyalar Kaynaklar panelinde gösterilir ancak yüklenemez.
Bu sorunu düzeltmek için C/C++ uzantı seçenekleri vardır. Bunu rastgele yolları ve hedefleri yeniden eşlemek için Geliştirici Araçları'nın kaynakları bulmasına yardımcı olabilirsiniz.
Örneğin, ana makinenizdeki proje C:\src\my_project
yolunun altındaysa ancak bu yolun /mnt/c/src/my_project
olarak temsil edildiği bir Docker kapsayıcısında derlendiyse bu yolları ön ek olarak belirterek hata ayıklama sırasında yeniden eşleyebilirsiniz:
Eşleşen ilk ön ek "kazanır". Diğer C++ öğelerine aşinaysanız
bu seçenek set substitute-path
komutuna benzerdir
veya LLDB'de target.source-map
ayarı yapın.
Optimize edilmiş derlemelerde hata ayıklama
Diğer tüm dillerde olduğu gibi, optimizasyonlar devre dışı bırakılırsa hata ayıklama en iyi şekilde çalışır. Optimizasyonlar, işlevleri birbirine satır içi olarak yerleştirebilir, kodu yeniden sıralayabilir veya kod parçalarını tamamen kaldırabilir. Tüm bunların hata ayıklayıcıyı ve dolayısıyla kullanıcı olarak sizi şaşırtma olasılığı vardır.
Daha sınırlı bir hata ayıklama deneyiminin sizin için
sakıncası yoksa ve yine de
hata ayıklamak istiyorsanız optimizasyonların çoğu
( satır içi işlevin hariç tutulması dışında) beklenenler. Kalan sorunları gelecekte ele almayı planlıyoruz ancak şimdilik -O
düzeyinde optimizasyonlarla derleme yaparken devre dışı bırakmak için lütfen -fno-inline
kullanın. Örneğin:
emcc -g temp.c -o temp.html \ -O3 -fno-inline
Hata ayıklama bilgilerini ayırma
Hata ayıklama bilgileri, kodunuz, tanımlanmış türler, değişkenler, işlevler, kapsamlar ve konumlar (hata ayıklayıcı için yararlı olabilecek her şey) hakkında birçok ayrıntıyı korur. Sonuç olarak, genellikle daha fazla bilgi edineceksiniz.
WebAssembly modülünün yüklenmesini ve derlenmesini hızlandırmak için
bu hata ayıklama bilgilerini farklı bir WebAssembly
dosyası olarak kaydedebilirsiniz. Bunu Emscripten'de yapmak için-gseparate-dwarf=…
istediğiniz bir dosya adına sahip olmanız gerekir:
emcc -g temp.c -o temp.html \ -gseparate-dwarf=temp.debug.wasm
Bu durumda, ana uygulama yalnızca bir dosya adı saklar
temp.debug.wasm
ve yardımcı uzantı,
Geliştirici Araçları'nı açtığınızda da yükleyebilirsiniz.
Yukarıda açıklanan optimizasyonlarla birlikte kullanıldığında bu özellik, uygulamanızın neredeyse optimize edilmiş üretim derlemelerini göndermek ve daha sonra yerel taraftaki bir dosyayla bu derlemelerde hata ayıklama yapmak için bile kullanılabilir. Bu durumda, uzantının yan dosyayı bulmasına yardımcı olmak için saklanan URL'yi de geçersiz kılmamız gerekir. Örneğin:
emcc -g temp.c -o temp.html \ -O3 -fno-inline \ -gseparate-dwarf=temp.debug.wasm \ -s SEPARATE_DWARF_URL=file://[local path to temp.debug.wasm]
Devam etmek için...
Vay canına, bir sürü yeni özellik sunduk.
Tüm bu yeni entegrasyonlarla Chrome Geliştirici Araçları, yalnızca JavaScript için değil, C ve C++ uygulamaları için de geçerli, güçlü ve kullanışlı bir hata ayıklayıcı haline gelir. Böylece, çeşitli teknolojilerde geliştirilen uygulamaları paylaşılan, platformlar arası bir web'e taşımak hiç olmadığı kadar kolay hale gelir.
Ancak yolculuğumuz henüz sona ermedi. Bundan sonra üzerinde çalışacağımız bazı konular:
- Hata ayıklama deneyimindeki sorunlu kısımları temizleme.
- Özel tür biçimlendiriciler için destek eklendi.
- WebAssembly uygulamaları için profil oluşturma özelliğinde iyileştirmeler üzerinde çalışıyoruz.
- Kullanılmayan kodun bulunmasını kolaylaştırmak için kod kapsamı desteği eklendi.
- Konsol değerlendirmesinde ifadeler için sağlanan desteği iyileştirme.
- Daha fazla dil için destek eklendi.
- …ve daha fazlası!
Bu sırada, mevcut beta sürümünü kendi kodunuzda deneyerek ve karşılaştığınız sorunları https://issues.chromium.org/issues/new?noWizard=true&template=0&component=1456350 adresinden bildirerek bize yardımcı olabilirsiniz.
Önizleme kanallarını indirme
Varsayılan geliştirme tarayıcınız olarak Chrome Canary, Geliştirici veya Beta sürümünü kullanabilirsiniz. Bu önizleme kanalları en yeni Geliştirici Araçları özelliklerine erişmenizi, son teknoloji ürünü web platformu API'lerini test etmenizi ve kullanıcılarınızdan önce sitenizdeki sorunları bulmanızı sağlar.
Chrome Geliştirici Araçları ekibiyle iletişim kurma
Yayındaki yeni özellikler ve değişiklikler ya da DevTools ile ilgili başka bir konu hakkında konuşmak için aşağıdaki seçenekleri kullanın.
- crbug.com üzerinden bize öneri veya geri bildirim gönderin.
- Geliştirici Araçları sorunlarını bildirmek için Diğer seçenekler'i > Yardım > Geliştirici Araçları'nda Geliştirici Araçları ile ilgili sorunları bildirin.
- @ChromeDevTools adresinden tweet atabilirsiniz.
- DevTools'daki yeniliklerle ilgili YouTube videolarımız veya DevTools ipuçları YouTube videolarımız için yorum bırakın.