Memperluas Memory Inspector untuk proses debug C/C++

Di Chrome 92, kami memperkenalkan Memory Inspector, alat untuk memeriksa buffer memori linear. Dalam artikel ini, kita akan membahas cara meningkatkan kualitas Inspector untuk proses debug C/C++ dan masalah teknis yang dihadapi.

Berikut adalah beberapa postingan blog yang relevan jika Anda baru mengenal proses debug C/C++ dan Memory Inspector:

Pengantar

Memory Inspector memberi Anda opsi proses debug yang lebih canggih untuk buffer memori linear. Pada kasus C/C++, Anda dapat memeriksa objek memori C/C++ di WebAssembly Memory.

Mengenali byte objek Anda di antara memori WebAssembly di sekitarnya adalah poin masalah. Anda harus mengetahui ukuran objek dan menghitung byte dari awal objek. Dalam screenshot di bawah, byte pertama dari array int32 10 elemen dipilih, tetapi tidak segera jelas byte lain mana yang termasuk dalam array. Pasti menyenangkan jika Anda bisa langsung mengenali semua {i>byte<i} yang dimiliki objek tersebut?

Screenshot pemeriksa memori asli dengan satu byte yang ditandai

Sorotan objek di Memory Inspector

Mulai dari Chrome 107, Memory Inspector menandai semua byte objek memori C/C++. Ini membantu Anda membedakan mereka dari memori di sekitar.

Screenshot pemeriksa memori yang diupdate dengan array yang disorot dengan warna cerah

Tonton video di bawah untuk melihat cara kerja Memory Inspector. Saat Anda menampilkan array x di Memory Inspector, memori yang ditandai akan muncul di Memory Viewer bersama dengan chip baru tepat di atasnya. Chip ini mengingatkan Anda nama dan jenis memori yang ditandai. Klik chip untuk beralih ke memori objek. Jika Anda mengarahkan kursor ke chip, ikon silang akan muncul – klik chip tersebut untuk menghapus sorotan.

Saat Anda memilih byte di luar objek yang diperiksa, sorotan akan beralih fokus agar tidak mengganggu Anda. Untuk memfokuskannya kembali, klik salah satu byte objek atau chip lagi.

Dukungan untuk penyorotan objek tidak terbatas pada array. Anda juga dapat memeriksa struct, objek, dan pointer. Perubahan ini mempermudah penjelajahan memori aplikasi C/C++ Anda.

Ingin mencobanya? Anda harus:

  • Memiliki Chrome 107 atau yang lebih baru.
  • Instal Ekstensi DWARF C/C++.
  • Aktifkan proses debug DWARF di DevTools > Setelan. Settings > Experiments > WebAssemble Debugging: Aktifkan dukungan DWARF.
  • Buka halaman demo ini.
  • Ikuti petunjuk di halaman tersebut.

Contoh proses debug

Di bagian ini, mari kita lihat bug mainan untuk menggambarkan cara menggunakan Memory Inspector untuk proses debug C/C++. Dalam contoh kode di bawah ini, programmer membuat array bilangan bulat dan memutuskan untuk menggunakan aritmetika pointer untuk memilih elemen terakhir. Sayangnya, {i>programmer<i} membuat kesalahan dalam perhitungan pointer mereka dan sekarang program tidak mencetak elemen terakhir, melainkan mencetak nilai-nilai yang tidak masuk akal.

#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;
}

Programmer beralih ke Memory Inspector untuk men-debug masalah. Anda dapat mengikuti demo ini. Pertama-tama, mereka memeriksa array di Memory Inspector dan melihat bahwa array numbers hanya berisi bilangan bulat 1, 2, 3, dan 4, seperti yang diharapkan.

Screenshot pemeriksa memori yang terbuka dengan array int32 yang diperiksa. Semua elemen array ditandai.

Selanjutnya, metode tersebut mengungkapkan variabel lastNumber dari panel Scope dan melihat bahwa pointer mengarah ke bilangan bulat di luar array. Dibekali dengan pengetahuan ini, programmer menyadari bahwa mereka salah menghitung offset pointer di baris 8. Seharusnya ptr + arraySize - 1.

Screenshot pemeriksa memori yang terbuka menampilkan memori yang ditandai yang ditunjukkan oleh pointer bernama ‘lastNumber’. Memori yang ditandai berada tepat setelah byte terakhir dari array yang disorot sebelumnya.

Meskipun ini adalah contoh mainan, contoh ini menggambarkan bagaimana penyorotan objek secara efektif menyampaikan ukuran dan posisi objek memori, yang dapat membantu Anda lebih memahami apa yang terjadi di dalam memori aplikasi C/C++.

Cara DevTools mengetahui apa yang harus ditandai

Di bagian ini, kita akan melihat ekosistem alat yang memungkinkan proses debug C/C++. Secara khusus, Anda akan mempelajari bagaimana DevTools, V8, Ekstensi DWARF C/C++, dan Emscripten memungkinkan proses debug C/C++ di Chrome.

Untuk memaksimalkan kemampuan proses debug C/C++ di DevTools, Anda memerlukan dua hal:

  • Ekstensi DWARF C/C++ yang diinstal di Chrome
  • File sumber C/C++ yang dikompilasi ke WebAssembly dengan compiler Emscripten terbaru seperti yang ditunjukkan dalam postingan blog ini

Mengapa? V8 , mesin JavaScript dan WebAssembly Chrome, tidak dapat mengeksekusi C atau C++. Berkat Emscripten, compiler C/C++ ke WebAssembly, Anda dapat mengompilasi aplikasi yang dibangun di C atau C++ sebagai WebAssembly dan menjalankannya di browser.

Selama kompilasi, emscripten akan menyematkan data debug DWARF ke dalam biner Anda. Pada dasarnya, data ini membantu ekstensi untuk mengetahui variabel WebAssembly mana yang sesuai dengan variabel C/C++ Anda, dan banyak lagi. Dengan cara ini, DevTools dapat menunjukkan kepada Anda variabel C++ meskipun V8 sebenarnya menjalankan WebAssembly. Jika Anda ingin tahu, baca postingan blog ini untuk melihat contoh data debug DWARF.

Jadi, apa yang sebenarnya terjadi saat Anda mengungkapkan lastNumber? Segera setelah Anda mengklik ikon memori, DevTools akan memeriksa variabel mana yang ingin diperiksa. Kemudian, ekstensi membuat kueri terkait jenis data dan lokasi lastNumber. Segera setelah ekstensi merespons dengan informasi tersebut, Memory Inspector dapat menampilkan potongan memori yang relevan dan mengetahui jenisnya, serta dapat menunjukkan ukuran objek kepada Anda.

Jika melihat lastNumber dalam contoh sebelumnya, Anda mungkin memperhatikan bahwa kita telah memeriksa lastNumber: int *, tetapi chip di Memory Inspector menyatakan *lastNumber: int, apa masalahnya? Pemeriksa menggunakan dereferencing pointer bergaya C++ untuk menunjukkan jenis objek yang ditampilkan kepada Anda. Jika Anda memeriksa pointer, pemeriksa akan menunjukkan kepada Anda apa yang ditunjuk.

Mempertahankan sorotan pada langkah debugger

Saat Anda menampilkan objek di Memory Inspector dan melangkah dengan debugger, Inspector akan mempertahankan sorotan jika menurutnya objek tersebut masih berlaku. Awalnya, kami tidak memiliki fitur ini dalam rencana kami, tetapi kami segera menyadari bahwa hal ini akan mengganggu pengalaman proses debug Anda. Bayangkan Anda harus memeriksa ulang array setelah melakukan setiap langkah seperti dalam video di bawah.

Saat debugger mencapai titik henti sementara baru, Memory Inspector akan mengkueri V8 dan ekstensi untuk variabel yang terkait dengan sorotan sebelumnya. Kemudian, lokasi dan jenis objek akan dibandingkan. Jika cocok, sorotan akan tetap ada. Pada video di atas, ada penulisan for-loop pada array x. Operasi ini tidak mengubah jenis atau posisi array, sehingga tetap disorot.

Anda mungkin bertanya-tanya bagaimana pengaruhnya terhadap pointer. Jika Anda memiliki pointer yang disorot dan menetapkannya kembali ke objek lain, posisi lama dan baru dari objek yang disorot akan berbeda dan sorotan akan menghilang. Karena objek yang baru diarahkan dapat berada di mana saja dalam WebAssembly Memory dan kemungkinan akan memiliki sedikit hubungan dengan lokasi memori sebelumnya, menghapus sorotan akan lebih jelas daripada melompat ke lokasi memori baru. Anda dapat menandai pointer lagi dengan mengklik ikon memorinya di panel Scope.

Kesimpulan

Artikel ini menjelaskan peningkatan kami terhadap Memory Inspector untuk proses debug C/C++. Kami harap fitur baru ini akan menyederhanakan proses debug memori aplikasi C/C++ Anda. Jika Anda memiliki saran untuk meningkatkan kualitasnya lebih lanjut, beri tahu kami dengan melaporkan bug.

Langkah selanjutnya

Untuk mempelajari lebih lanjut, lihat: