Debug project Anda dengan Debugger Visual Studio (LLDB) saat menggunakan Android Game Development Extension.
Menjalankan debugger
Sebelum dapat menjalankan debugger, Anda harus dapat membuat, men-deploy, dan menjalankan game di Android. Lihat bagian Menjalankan contoh untuk detailnya.
Setelah yakin dapat menjalankan game tanpa debugger, Anda dapat menggunakan debugger dengan menekan F5 atau memilih item Start Debugging di menu Debug. Anda akan melihat dialog saat debugger dipasang ke game.
Meluncurkan debugger memerlukan waktu antara 10 detik hingga 1 menit atau lebih, bergantung pada ukuran aplikasi Anda dan jumlah simbol yang perlu dimuat saat dimulai. Lebih banyak waktu diperlukan saat memasang debugger ke perangkat baru untuk pertama kalinya karena harus mendownload beberapa library Android dari perangkat ke mesin host. Jika upaya pertama dengan perangkat baru memakan waktu lebih dari 1 menit, pertimbangkan untuk membatalkan sesi debug, lalu memulai ulang.
Saat Anda menjalankan debugger dengan cara ini, game dimulai dalam mode Waiting for Debugger dan tidak akan menjalankan kode game apa pun hingga debugger terhubung. Ini juga memungkinkan Anda untuk men-debug bagian inisialisasi game.
Anda dapat menemukan informasi selengkapnya tentang fitur debugger Visual Studio tertentu dengan membaca Dokumentasi Visual Studio.
Memasang ke proses
Jika ingin men-debug game yang sudah berjalan di perangkat fisik atau virtual, Anda dapat memasang debugger ke proses dari Visual Studio.
Di Visual Studio, pastikan solusi Android terbuka, lalu:
- Buka menu Debug dan pilih Attach to Process....
- Dari dropdown Transport, pilih Android Game Development Extension.
- Dari dropdown Qualifier, pilih perangkat Android Anda.
- Pilih proses game dari daftar proses yang tersedia dan klik Attach.
Mengeksekusi perintah LLDB.Shell
Dengan sesi proses debug aktif, gunakan Command Window Visual Studio untuk menjalankan perintah LLDB.Shell.
Format perintah:
LLDB.Shell [command]
Contoh:
>LLDB.Shell expr myIntVariable = 9
Status: Success
Output Message:
(int) $2 = 9
Visualisasi data
Penentu Format
Anda dapat mengubah format untuk menampilkan nilai di jendela Autos, Locals, Watch, dan DataTip variabel menggunakan penentu format.
Penentu format terdapat di akhir ekspresi. Penentu format dimulai dengan koma
yang diikuti dengan string pendek. Misalnya, penentu ,x
dalam ekspresi
_myInt,x
akan memformat myInt sebagai heksadesimal huruf kecil.
Penentu format dapat digunakan langsung di jendela Watch atau Autos, Locals, dan DataTip dengan menambahkannya ke ekspresi Natvis. Lihat Natvis untuk informasi selengkapnya.
Daftar penentu dukungan
Nama Format | Penentu | Deskripsi |
---|---|---|
boolean | B | tampilkan ini sebagai boolean benar/salah, menggunakan aturan kebiasaan bahwa 0 adalah salah dan yang lainnya benar |
biner | b | tampilkan ini sebagai urutan bit |
biner, tanpa awalan 0b | bb | tampilkan ini sebagai urutan bit tanpa awalan 0b |
byte | y | tampilkan byte, tetapi coba tampilkan juga sebagai karakter ASCII mis. (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
byte dengan ASCII | Y | tampilkan byte, tetapi coba tampilkan juga sebagai karakter ASCII mis. (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
karakter | c | tampilkan byte sebagai karakter ASCII mis. (int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0 |
karakter yang dapat dicetak | C | tampilkan byte sebagai karakter ASCII yang dapat dicetak mis. (int *) c.sp.x = P.._.... |
float kompleks | F | tafsirkan nilai ini sebagai bagian nyata dan khayalan dari bilangan floating point kompleks mis. (int *) c.sp.x = 2.76658e+19 + 4.59163e-41i |
desimal | d, i | tampilkan ini sebagai bilangan bulat bertanda (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai bilangan bulat dengan tanda) |
enumerasi | E,en | tampilkan ini sebagai enumerasi, dengan mencetak nama nilai jika tersedia, atau nilai bilangan bulat jika tidak mis. (enum enumType) val_type = eValue2 |
heksadesimal - huruf kecil | x, h | tampilkan ini dalam notasi heksadesimal huruf kecil (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai heks) |
heksadesimal - huruf besar | X, H | tampilkan ini dalam notasi heksadesimal huruf besar (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai heks) |
heksadesimal - huruf kecil, tanpa awalan 0x | xb, hb | tampilkan ini dalam notasi heksadesimal huruf kecil tanpa awalan 0x (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai heks) |
heksadesimal - huruf besar, tanpa awalan 0x | Xb, Hb | tampilkan ini dalam notasi heksadesimal huruf besar tanpa awalan 0x (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai heks) |
float | f | tampilkan ini sebagai bilangan floating point (ini tidak menjalankan cast, melainkan hanya menafsirkan byte sebagai nilai floating point IEEE754) |
oktal | o | tampilkan ini dalam notasi oktal |
jenis OS | O | tampilkan ini sebagai MacOS OSType mis. (float) x = '\n\x1f\xd7\n' |
string - string C | s | tampilkan ini sebagai string C yang diakhiri dengan 0 mis. "halo dunia" |
string - string C, tanpa tanda petik | sb | tampilkan ini sebagai string C yang diakhiri dengan 0 tanpa tanda petik mis. halo dunia |
string - UTF-8 | s8 | tampilkan ini sebagai string UTF-8 yang diakhiri dengan 0 mis. u8"halo dunia ☕" |
string - UTF-8, tanpa tanda petik | s8b | tampilkan ini sebagai string UTF-8 yang diakhiri dengan 0 tanpa tanda petik mis. halo dunia ☕ |
string - UTF-16 | su | tampilkan ini sebagai string UTF-16 yang diakhiri dengan 0 mis. u"halo dunia ☕" |
string - UTF-16, tanpa tanda petik | sub | tampilkan ini sebagai string UTF-16 yang diakhiri dengan 0 tanpa tanda petik mis. halo dunia ☕ |
string - UTF-32 | s32 | tampilkan ini sebagai string UTF-32 yang diakhiri dengan 0 mis. U"halo dunia ☕" |
string - UTF-32, tanpa tanda petik | s32b | tampilkan ini sebagai string UTF-32 yang diakhiri dengan 0 tanpa tanda petik mis. halo dunia ☕ |
unicode16 | U | tampilkan ini sebagai karakter UTF-16 mis. (float) x = 0xd70a 0x411f |
unicode32 | U32 | tampilkan ini sebagai karakter UTF-32 mis. (float) x = 0x411fd70a |
desimal tidak bertanda | u | tampilkan ini sebagai bilangan bulat tidak bertanda (ini tidak menjalankan cast, melainkan hanya menampilkan byte sebagai bilangan bulat tidak bertanda) |
pointer | p | tampilkan ini sebagai pointer native (kecuali jika ini benar-benar pointer, alamat yang dihasilkan mungkin tidak valid) |
bilangan bulat kompleks | I | tafsirkan nilai ini sebagai bagian nyata dan khayalan dari bilangan bulat kompleks mis. (int *) pointer = 1048960 + 1i |
array karakter | a | tampilkan ini sebagai array karakter mis. (char) *c.sp.z = {X} |
Raw | ! | format raw, mengabaikan penyesuaian tampilan jenis data apa pun |
Natvis
Framework Natvis memungkinkan Anda menyesuaikan cara Visual Studio menampilkan jenis native di jendela variabel debugger. Misalnya, gunakan Natvis untuk menyesuaikan tampilan jendela Watch, Locals, dan Data Tips.
Fitur Natvis diaktifkan secara default, tetapi dapat dinonaktifkan dari Visual Studio dengan menyetel tanda Tools > Options > Android Game Development Extension > Natvis ke Disabled.
Memuat file Natvis
Visual Studio memuat file Natvis dari tiga lokasi yang tercantum di bawah ini dan memuat ulang file tersebut setiap kali Anda memulai sesi proses debug. File harus mematuhi skema Natvis Visual Studio 2017.
- File
.natvis
yang merupakan bagian dari item solusi level atas atau project yang dimuat. - Direktori khusus pengguna
(
%USERPROFILE%\Documents\Visual Studio 2017\Visualizers
) - Direktori seluruh sistem
(
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers
)
Memuat ulang file Natvis
Muat ulang file Natvis selama sesi debug berlangsung dengan mengevaluasi .natvisreload
di
Command Window atau jendela Watch.
Contoh file Natvis
Contoh file Natvis ini mencakup semua tag dan atribut yang saat ini didukung.
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="demo::Vector<*>">
<AlternativeType Name="MySimilarVectorType<*>"/>
<!-- Included to show the <SmartPointer> feature is supported. -->
<SmartPointer Optional="true" Usage="Minimal">ptr</SmartPointer>
<!-- Included to show the <DisplayString> feature is supported. -->
<DisplayString Condition="_size == 0" Optional="true">()</DisplayString>
<DisplayString Condition="_size == 1">(x={_items[0]})</DisplayString>
<DisplayString Condition="_size == 2">(x={_items[0]}, y={_items[1]})</DisplayString>
<DisplayString Condition="_size == 3">(x={_items[0]}, y={_items[1]}, z={_items[2]})</DisplayString>
<DisplayString>[Size={_size,x}] (x={_items[0]}, y={_items[1]}, z={_items[2]}, ...)</DisplayString>
<!-- Included to show the <StringView> feature is supported. -->
<StringView Condition="true" Optional="true">_stringViewText</StringView>
<Expand HideRawView="false">
<!-- Included to show the <Item> feature is supported. -->
<Item Name="X" Condition="_size < 4 && _size >= 1" Optional="true">_items[0]</Item>
<Item Name="Y" Condition="_size < 4 && _size >= 2" Optional="true">_items[1]</Item>
<Item Name="Z" Condition="_size < 4 && _size >= 3" Optional="true">_items[2]</Item>
<!-- Included to show the <ArrayItems> feature is supported. -->
<ArrayItems Condition="_size >= 4" Optional="true">
<Size Condition="true" Optional="true">_size</Size>
<ValuePointer Condition="true">_items</ValuePointer>
</ArrayItems>
<!-- Included to show the <IndexListItems> feature is supported. -->
<IndexListItems Condition="true" Optional="true">
<Size Condition="true" Optional="true">_listSize</Size>
<ValueNode Condition="true">_list[%i]</ValueNode>
</IndexListItems>
<!-- Included to show the <LinkedListItems> feature is supported. -->
<LinkedListItems Condition="true" Optional="true">
<Size Optional="true">_listSize</Size>
<HeadPointer>_head</HeadPointer>
<NextPointer>_next</NextPointer>
<ValueNode>_value</ValueNode>
</LinkedListItems>
<!-- Included to show the <ExpandedItem> feature is supported. -->
<ExpandedItem Condition="true" Optional="true">_childVar</ExpandedItem>
<!-- Included to show the <Synthetic> feature is supported. -->
<Synthetic Name="[Size]" Condition="true" Optional="true">
<DisplayString>_size</DisplayString>
<Expand HideRawView="true">
<!-- Any supported <Expand> sub-tags. -->
</Expand>
</Synthetic>
<!-- Included to show the <TreeItems> feature is supported. -->
<TreeItems Condition="true" Optional="true">
<Size>_treeSize</Size>
<HeadPointer>_head</HeadPointer>
<LeftPointer>_left</LeftPointer>
<RightPointer>_right</RightPointer>
<ValueNode>_value</ValueNode>
</TreeItems>
<!-- Included to show format specifiers are supported. -->
<Item Name="[Hex Dump at {_index,x}]">myInt[_index],x</Item>
</Expand>
</Type>
</AutoVisualizer>
Menulis file Natvis
Visual Studio mendukung pembuatan otorisasi file Natvis Anda sendiri. Untuk informasi lebih lanjut menyesuaikan jendela variabel debugger. MSDN.
Men-debug file Natvis
Dalam beberapa kasus, error akan ditampilkan sebagai Value variabel (mis. di
jendela Auto, Watch, dll.). Contoh: <error: use of undeclared
identifier 'missingVar'>
Anda dapat mengakses detail selengkapnya tentang error tersebut dengan membuka file GoogleAndroid.log
dari toolbar Android Game Development Extension.
Batasan umum
Jika tidak tercantum dalam contoh file di atas, berarti saat ini tag atau atribut Anda tidak didukung. Visual Studio mengabaikan tag dan atribut yang tidak didukung, sehingga Anda dapat membiarkannya dalam file Natvis yang ada dan file tersebut akan berfungsi, asalkan menggunakan skema kami.
Atribut
Usage
, meskipun diperlukan oleh skema, tidak didukung untuk<SmartPointer>
. Namun, LLDB tidak membatasi akses ke operator yang ditentukan dalam C++, sehingga setiap operator yang diperlukan dapat ditentukan dalam C++.