Memperluas Memory Inspector untuk proses debug C/C++

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

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

Pengantar

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

Mengidentifikasi byte objek Anda di antara memori WebAssembly di sekitarnya adalah poin masalah. Anda harus mengetahui ukuran objek dan menghitung byte dari awal objek. Pada screenshot di bawah, byte pertama dari array int32 10 elemen dipilih, tetapi tidak langsung jelas byte lain mana yang termasuk dalam array. Bukankah lebih baik jika Anda dapat langsung mengenali semua byte yang termasuk dalam objek?

Screenshot pemeriksa memori asli dengan satu byte yang ditandai

Penandaan objek di Memory Inspector

Mulai Chrome 107, Memory Inspector menandai semua byte objek memori C/C++. Hal ini membantu Anda membedakannya dari memori di sekitarnya.

Screenshot pemeriksa memori yang diupdate dengan array yang ditandai dengan 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 beserta chip baru tepat di atasnya. Chip ini mengingatkan Anda nama dan jenis memori yang ditandai. Klik chip untuk membuka memori objek. Jika Anda mengarahkan kursor ke chip, ikon silang akan muncul. Klik ikon tersebut untuk menghapus sorotan.

Saat Anda memilih byte di luar objek yang Anda periksa, sorotan akan difokuskan agar tidak mengganggu Anda. Untuk memfokuskan ulang, klik byte objek atau chip lagi.

Dukungan untuk sorotan objek tidak terbatas pada array. Anda juga dapat memeriksa struct, objek, dan pointer. Perubahan ini mempermudah eksplorasi 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: Enable DWARF support.
  • Buka halaman demo ini.
  • Ikuti petunjuk di halaman.

Contoh proses debug

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

#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 tersebut. 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 disorot.

Selanjutnya, mereka menampilkan variabel lastNumber dari panel Cakupan dan melihat bahwa pointer mengarah ke bilangan bulat di luar array. Dengan pengetahuan ini, programmer menyadari bahwa ia salah menghitung offset pointer di baris 8. Seharusnya ptr + arraySize - 1.

Screenshot pemeriksa memori yang terbuka yang menampilkan memori yang ditandai yang ditunjuk oleh pointer bernama &#39;lastNumber&#39;. Memori yang ditandai terletak tepat setelah byte terakhir dari array yang ditandai sebelumnya.

Meskipun ini adalah contoh mainan, contoh ini mengilustrasikan bagaimana sorotan 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 mencari tahu apa yang harus disorot

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

Untuk mendapatkan kemampuan maksimal 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

Namun, mengapa? V8, mesin JavaScript dan WebAssembly Chrome, tidak tahu cara menjalankan C atau C++. Berkat Emscripten, compiler C/C++ ke WebAssembly, Anda dapat mengompilasi aplikasi yang dibuat dalam C atau C++ sebagai WebAssembly dan menjalankannya di browser.

Selama kompilasi, emscripten akan menyematkan data debug DWARF ke dalam biner Anda. Pada tingkat tinggi, data ini membantu ekstensi untuk mengetahui variabel WebAssembly mana yang sesuai dengan variabel C/C++ Anda, dan lainnya. Dengan cara ini, DevTools dapat menampilkan variabel C++ meskipun V8 sebenarnya menjalankan WebAssembly. Jika Anda ingin tahu, lihat postingan blog ini untuk contoh data debug DWARF.

Jadi, apa yang sebenarnya terjadi saat Anda menampilkan lastNumber? Segera setelah Anda mengklik ikon memori, DevTools akan memeriksa variabel yang ingin Anda periksa. Kemudian, ekstensi akan membuat kueri berdasarkan jenis data dan lokasi lastNumber. Segera setelah ekstensi merespons dengan info tersebut, Memory Inspector dapat menampilkan bagian memori yang relevan dan mengetahui jenisnya, serta dapat menampilkan ukuran objek kepada Anda.

Jika melihat lastNumber dalam contoh sebelumnya, Anda mungkin melihat bahwa kita sudah memeriksa lastNumber: int *, tetapi chip di Memory Inspector menyebutkan *lastNumber: int. Apa penyebabnya? Inspector menggunakan dereferensi pointer bergaya C++ untuk menunjukkan jenis objek yang ditampilkan kepada Anda. Jika Anda memeriksa pointer, pemeriksa akan menunjukkan apa yang ditunjuknya.

Mempertahankan sorotan pada langkah debugger

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

Saat debugger mencapai titik henti sementara baru, Memory Inspector akan kembali membuat kueri V8 dan ekstensi untuk variabel yang terkait dengan sorotan sebelumnya. Kemudian, fitur ini membandingkan lokasi dan jenis objek. Jika cocok, sorotan akan tetap ada. Dalam video di atas, ada loop for yang menulis ke array x. Operasi ini tidak mengubah jenis atau posisi array, sehingga tetap tersorot.

Anda mungkin bertanya-tanya bagaimana hal ini memengaruhi pointer. Jika Anda memiliki pointer yang ditandai dan menetapkannya kembali ke objek lain, posisi lama dan baru objek yang ditandai akan berbeda dan tanda akan hilang. Karena objek yang baru ditunjuk dapat berada di mana saja di Memori WebAssembly 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 Cakupan.

Kesimpulan

Artikel ini menjelaskan peningkatan kami pada 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 meningkatkannya lebih lanjut, beri tahu kami dengan melaporkan bug.

Langkah selanjutnya

Untuk mempelajari lebih lanjut, lihat: