Chrome Geliştirici Zirvesi 2020'de, Chrome'un WebAssembly uygulamaları için hata ayıklama desteğini web'de ilk kez tanıttık. Ekip o zamandan beri, geliştirici deneyimini büyük ve hatta devasa uygulamalarda ölçeklendirmek için çok fazla enerji yatırımı yapmıştır. Bu gönderide, farklı araçlara eklediğimiz (veya çalıştırdığımız) düğmeleri ve bunları nasıl kullanacağınızı göstereceğiz.
Ölçeklenebilir hata ayıklama
2020 yayınımızda kaldığımız yerden devam edelim. O zamanlar karşılaştığımız örneği aşağıda bulabilirsiniz:
#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();
}
Bu hâlâ oldukça küçük bir örnek ve büyük bir uygulamada karşılaşacağınız gerçek sorunların hiçbirini büyük olasılıkla görmeyeceksiniz, ancak yine de size yeni özelliklerin neler olduğunu gösterebiliriz. Hızlı ve kolay bir şekilde ayarlayıp kendiniz deneyebilirsiniz!
Son gönderide, bu örneğin nasıl derlenip hata ayıklanacağını açıkladık. Bunu tekrar yapalım ancak //performance//.
$ emcc -sUSE_SDL=2 -g -O0 -o mandelbrot.html mandelbrot.cc -sALLOW_MEMORY_GROWTH
Bu komut, 3 MB'lık wasm ikili programını üretir. Bu işlerin büyük kısmı da tahmin edebileceğiniz gibi hata ayıklama bilgileridir. Bunu llvm-objdump
aracı [1] ile doğrulayabilirsiniz. Örneğin:
$ llvm-objdump -h mandelbrot.wasm
mandelbrot.wasm: file format wasm
Sections:
Idx Name Size VMA Type
0 TYPE 0000026f 00000000
1 IMPORT 00001f03 00000000
2 FUNCTION 0000043e 00000000
3 TABLE 00000007 00000000
4 MEMORY 00000007 00000000
5 GLOBAL 00000021 00000000
6 EXPORT 0000014a 00000000
7 ELEM 00000457 00000000
8 CODE 0009308a 00000000 TEXT
9 DATA 0000e4cc 00000000 DATA
10 name 00007e58 00000000
11 .debug_info 000bb1c9 00000000
12 .debug_loc 0009b407 00000000
13 .debug_ranges 0000ad90 00000000
14 .debug_abbrev 000136e8 00000000
15 .debug_line 000bb3ab 00000000
16 .debug_str 000209bd 00000000
Bu çıkış, oluşturulan wasm dosyasındaki tüm bölümleri gösterir. Bunların çoğu standart WebAssembly bölümleridir, ancak adı .debug_
ile başlayan birkaç özel bölüm de vardır. İkili program, hata ayıklama bilgilerimizi burada içerir. Tüm boyutları topladığımızda, hata ayıklama bilgilerinin 3 MB'lık dosyamızın yaklaşık 2,3 MB'ını oluşturduğunu görürüz. emcc
komutunu da time
yaparsak makinemizde çalışmasının yaklaşık 1, 5 saniye sürdüğünü görürüz. Bu rakamlar iyi bir başlangıç noktasıdır ancak o kadar küçüktür ki büyük olasılıkla kimse bunlara dikkat çekemez. Ancak gerçek uygulamalarda, hata ayıklama ikili programı kolayca GB cinsinden bir boyuta ulaşabilir ve derlemesi birkaç dakika sürer.
Binaryen atlanıyor
Emscripten ile bir wasm uygulaması oluştururken, uygulamanın son derleme adımlarından biri Binaryen optimize ediciyi çalıştırmaktır. Binaryen, WebAssembly (benzer) ikili programlarını optimize eden ve yasal hâle getiren bir derleyici araç setidir. Binaryen'i derlemenin bir parçası olarak çalıştırmak oldukça pahalıdır ancak yalnızca belirli koşullarda gereklidir. Hata ayıklama derlemelerinde, Binaryen geçişlerine ihtiyaç duymadığımız takdirde derleme süresini önemli ölçüde hızlandırabiliriz. En yaygın olarak gereken Binaryen geçişi, 64 bit tam sayı değerleri içeren işlev imzalarını yasallaştırmak içindir. -sWASM_BIGINT
ile WebAssembly BigInt entegrasyonunu etkinleştirerek bunu önleyebiliriz.
$ emcc -sUSE_SDL=2 -g -O0 -o mandelbrot.html mandelbrot.cc -sALLOW_MEMORY_GROWTH -sWASM_BIGINT -sERROR_ON_WASM_CHANGES_AFTER_LINK
İyi bir önlem olarak -sERROR_ON_WASM_CHANGES_AFTER_LINK
işaretini belirledik. Binaryen'in ne zaman çalıştığını ve ikili programı beklenmedik bir şekilde yeniden yazdığını algılamaya yardımcı olur. Bu sayede hızlı yolda olduğumuzdan emin olabiliriz.
Örneğimiz oldukça küçük olsa da Binaryen'i atlamanın etkisini görebiliriz. time
adlı kaynağa göre bu komut 1 saniyeden biraz daha kısa sürede çalışır. Yani öncesine göre yarım saniye daha hızlıdır.
Gelişmiş ince ayarlar
Giriş dosyası tarama atlanıyor
Normalde bir Emscripten projesini bağlarken emcc
, tüm giriş nesnesi dosyalarını ve kitaplıklarını tarar. Bunu, programınızdaki JavaScript kitaplık işlevleri ile yerel simgeler arasında kesin bağımlılıklar uygulamak için yapar. Daha büyük projelerde giriş dosyalarının (llvm-nm
kullanılarak) bu ek taraması, bağlantı süresini önemli ölçüde artırabilir.
Bunun yerine, emcc
parametresine JavaScript işlevlerinin tüm olası yerel bağımlılıklarını dahil etmesini bildiren -sREVERSE_DEPS=all
ile çalıştırılabilir. Bu, küçük bir kod boyutu ek yüküne sahiptir ancak bağlantı sürelerini hızlandırabilir ve hata ayıklama derlemelerinde yararlı olabilir.
Örneğimiz kadar küçük bir projede bu durum gerçek bir fark yaratmaz. Ancak projenizde yüzlerce, hatta binlerce nesne dosyası varsa bağlantı sürelerini anlamlı şekilde iyileştirebilirsiniz.
"Ad" bölümünü çıkarma
Büyük projelerde, özellikle de C++ şablonu çok fazla kullanılan projelerde, WebAssembly "name" bölümü çok büyük olabilir. Örneğimizde bu, toplam dosya boyutunun yalnızca küçük bir parçasıdır (yukarıdaki llvm-objdump
çıkışına bakın) ancak bazı durumlarda çok önemli olabilir. Uygulamanızın "ad" bölümü çok büyükse ve cüce hata ayıklama bilgileri hata ayıklama ihtiyaçlarınız için yeterliyse "ad" bölümünü çıkarmak avantajlı olabilir:
$ emstrip --no-strip-all --remove-section=name mandelbrot.wasm
Bu işlem, DWARF hata ayıklama bölümlerini korurken WebAssembly "name" bölümünü kaldırır.
Hata ayıklama fisyonu
Çok sayıda hata ayıklama verisi içeren ikili programlar hem derleme süresini hem de hata ayıklama süresini etkiler. Hata ayıklayıcının verileri yüklemesi ve "X yerel değişkeninin türü nedir?" gibi sorgulara hızlı bir şekilde yanıt verebilmek için bir dizin oluşturması gerekir.
Hata ayıklama fisyonu, bir ikili programın hata ayıklama bilgilerini iki bölüme ayırmamıza olanak tanır: biri ikili dosyada kalan, diğeri ise ayrı bir DWARF nesnesi (.dwo
) dosyasında bulunan. -gsplit-dwarf
işaretini Emscripten'e ileterek etkinleştirilebilir:
$ emcc -sUSE_SDL=2 -g -gsplit-dwarf -gdwarf-5 -O0 -o mandelbrot.html mandelbrot.cc -sALLOW_MEMORY_GROWTH -sWASM_BIGINT -sERROR_ON_WASM_CHANGES_AFTER_LINK
Aşağıda, farklı komutları ve hata ayıklama verileri olmadan, hata ayıklama verileriyle derleyerek ve son olarak hem hata ayıklama verileri hem de hata ayıklama hatalarıyla derleyerek hangi dosyaların oluşturulduğunu gösteriyoruz.
DWARF verileri bölünürken hata ayıklama verilerinin bir kısmı ikili programla birlikte yer alır, büyük kısmı ise mandelbrot.dwo
dosyasına yerleştirilir (yukarıda gösterildiği gibi).
mandelbrot
için yalnızca bir kaynak dosyamız var, ancak genellikle projeler bundan daha büyük ve birden fazla dosya içeriyor. Hata ayıklama fizyonları, her biri için bir .dwo
dosyası oluşturur. Hata ayıklayıcının mevcut beta sürümünün (0.1.6.1615) bu bölünmüş hata ayıklama bilgilerini yükleyebilmesi için bunların tümünü aşağıdaki gibi DWARF adı verilen bir pakette (.dwp
) toplamamız gerekir:
$ emdwp -e mandelbrot.wasm -o mandelbrot.dwp
Tek tek nesnelerden DWARF paketi oluşturmanın avantajı, fazladan bir dosya sunmanızdır. Şu anda ilerideki bir sürümde tüm nesneleri tek tek yüklemek için de çalışıyoruz.
DWARF 5 nedir?
Fark etmiş olabileceğiniz gibi, yukarıdaki emcc
komutuna bir işaret daha, -gdwarf-5
. Şu anda varsayılan olmayan DWARF sembollerinin 5. sürümünü etkinleştirmek, hata ayıklamayı daha hızlı başlatmamıza yardımcı olacak başka bir yöntemdir. Bu özellikle birlikte belirli bilgiler, varsayılan sürüm 4'ün dışarıda bıraktığı ana ikili programda depolanır. Özellikle, kaynak dosyalar grubunun tamamını yalnızca ana ikili programdan belirleyebiliriz. Bu, hata ayıklayıcının, tüm simge verilerini yükleyip ayrıştırmadan kaynak ağacının tamamını göstermek ve kesme noktalarını ayarlamak gibi temel işlemleri yapmasına olanak tanır. Bu da bölünmüş sembollerle hata ayıklamayı çok daha hızlı hale getirir. Bu sayede -gsplit-dwarf
ve -gdwarf-5
komut satırı işaretlerini her zaman birlikte kullanırız.
DWARF5 hata ayıklama biçimi sayesinde başka bir faydalı özelliğe de erişebilirsiniz. -gpubnames
işareti iletilirken oluşturulacak hata ayıklama verilerinde bir ad dizini bulunur:
$ emcc -sUSE_SDL=2 -g -gdwarf-5 -gsplit-dwarf -gpubnames -O0 -o mandelbrot.html mandelbrot.cc -sALLOW_MEMORY_GROWTH -sWASM_BIGINT -sERROR_ON_WASM_CHANGES_AFTER_LINK
Hata ayıklama oturumu sırasında simge aramaları genellikle bir varlığı ada göre arayarak (ör. bir değişken veya tür ararken) gerçekleşir. Ad dizini, doğrudan söz konusu adı tanımlayan derleme birimini işaret ederek bu aramayı hızlandırır. Ad dizini olmadığında, aradığımız adlandırılmış öğeyi tanımlayan doğru derleme birimini bulmak için tüm hata ayıklama verilerinin kapsamlı bir şekilde aranması gerekir.
Meraklı kişiler için: Hata ayıklama verilerine göz atma
DWARF verilerine göz atmak için llvm-dwarfdump
kullanabilirsiniz. Bir deneme yapalım:
llvm-dwarfdump mandelbrot.wasm
Bu sayede, hata ayıklama bilgilerine sahip olduğumuz "birimleri derle" (genel anlamda kaynak dosyalar) hakkında genel bilgi edinebilirsiniz. Bu örnekte, yalnızca mandelbrot.cc
için hata ayıklama bilgileri mevcuttur. Genel bilgiler bize bir iskelet birimimiz olduğunu bildirir. Bu, söz konusu dosyada eksik veriler olduğu ve kalan hata ayıklama bilgilerini içeren ayrı bir .dwo
dosyası olduğu anlamına gelir:
Bu dosyadaki diğer tablolara da göz atabilirsiniz. Örneğin, yer alır.llvm-dwarfdump -debug-line
Ayrı .dwo
dosyasında bulunan hata ayıklama bilgilerine de göz atabiliriz:
llvm-dwarfdump mandelbrot.dwo
Özet: Hata ayıklama çiplerini kullanmanın avantajı nedir?
Büyük uygulamalarla çalışan hata ayıklama bilgilerini bölmenin çeşitli avantajları vardır:
Daha hızlı bağlantı: Bağlayıcının artık hata ayıklama bilgilerinin tamamını ayrıştırması gerekmez. Bağlayıcıların genellikle ikili dosyadaki DWARF verilerinin tamamını ayrıştırması gerekir. Bağlayıcılar, hata ayıklama bilgilerinin büyük bir bölümünü ayrı dosyalara ayırarak daha küçük ikili dosyalarla çalışır. Bu da bağlantı sürelerinin daha hızlı olmasını sağlar (özellikle büyük uygulamalar için geçerlidir).
Daha hızlı hata ayıklama: Hata ayıklayıcı, bazı simge aramaları için
.dwo
/.dwp
dosyalarındaki ek simgeleri ayrıştırmayı atlayabilir. Bazı aramalarda (Wasm-C++ dosyalarının satır eşlemesi istekleri gibi) için ek hata ayıklama verilerine bakmamız gerekmez. Bu sayede, ek hata ayıklama verilerini yükleyip ayrıştırmak zorunda kalmadan zaman kazanabiliyoruz.
1: Sisteminizde llvm-objdump
uygulamasının son sürümü yoksa ve emsdk
kullanıyorsanız bunu emsdk/upstream/bin
dizininde bulabilirsiniz.
Önizleme kanallarını indirme
Varsayılan geliştirme tarayıcınız olarak Chrome Canary, Dev veya Beta'yı 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 özellikleri ve değişiklikleri ya da Geliştirici Araçları ile ilgili diğer her şeyi tartışmak için aşağıdaki seçenekleri kullanın.
- Öneri veya geri bildirimlerinizi crbug.com adresinden bize iletebilirsiniz.
- 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.
- Geliştirici Araçları YouTube videoları veya Geliştirici Araçları ipuçları YouTube videolarına yorum yazın.