Android Game Development Extension を使用している場合は、Visual Studio のデバッガ(LLDB)でプロジェクトをデバッグできます。
デバッガの実行
デバッガを実行するには、Android 上でゲームを作成、デプロイ、実行できる必要があります。詳細については、サンプルの実行セクションをご覧ください。
デバッガなしでゲームを実行できることを確認した後、デバッガを使用するには、F5 キーを押すか、[デバッグ] メニューの [デバッグの開始] を選択します。デバッガがゲームにアタッチしている間、ダイアログが表示されます。
アプリのサイズと起動時に読み込む必要があるシンボルの量に応じて、デバッガの起動には 10 秒から 1 分程度かかります。新しいデバイスに初めてアタッチする場合、デバッガはいくつかの Android ライブラリをデバイスからホストマシンにダウンロードする必要があるため、さらに時間がかかります。新しいデバイスでの最初の数回の試行に 1 分以上かかる場合は、デバッグ セッションをキャンセルして再起動してみてください。
この方法でデバッガを実行すると、ゲームは「デバッガを待機」モードで開始され、デバッガが接続されるまでゲームコードは実行されません。これにより、ゲームの初期化セクションをデバッグすることもできます。
Visual Studio のデバッガ機能の詳細については、Visual Studio のドキュメントをご覧ください。
プロセスへのアタッチ
物理デバイスまたは仮想デバイス上ですでに実行されているゲームをデバッグする場合は、Visual Studio からデバッガをプロセスにアタッチできます。
Visual Studio で Android ソリューションが開いていることを確認し、次の操作を行います。
- [デバッグ] メニューで [プロセスにアタッチ...] を選択します。
- [トランスポート] プルダウンで [Android Game Development Extension] を選択します。
- [修飾子] プルダウンで Android デバイスを選択します。
- 選択可能なプロセスのリストからゲームプロセスを選択し、[アタッチ] をクリックします。
LLDB.Shell コマンドの実行
デバッグ セッションをアクティブにした状態で、Visual Studio の [コマンド ウィンドウ] を使用して LLDB.Shell コマンドを実行します。
コマンドの形式:
LLDB.Shell [command]
例:
>LLDB.Shell expr myIntVariable = 9
Status: Success
Output Message:
(int) $2 = 9
データの可視化
フォーマット指定子
フォーマット指定子を使用して、[自動変数]、[ローカル]、[ウォッチ] の各ウィンドウや、変数の [データヒント] ウィンドウに表示される値の形式を変更できます。
フォーマット指定子は式の末尾にあります。カンマで始まり、その後に短い文字列が続きます。たとえば、_myInt,x
という式の ,x
指定子は、myInt の形式を小文字の 16 進数として指定します。
フォーマット指定子は [ウォッチ] ウィンドウで直接使用することも、[自動変数]、[ローカル]、[データヒント] の各ウィンドウで Natvis 式に付加して使用することもできます。詳しくは、Natvis をご覧ください。
サポートされる指定子のリスト
形式名 | 指定子 | 説明 |
---|---|---|
boolean | B | 0 が false で 0 以外が true であるという暗黙のルールを使用して、true / false のブール値として表示します。 |
binary | b | ビット シーケンスとして表示します。 |
binary - 先頭の 0b なし | bb | 0b プレフィックスなしのビット シーケンスとして表示します。 |
bytes | y | バイトを表示しますが、ASCII 文字としても表示しようとします。 例: (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
bytes with ASCII | Y | バイトを表示しますが、ASCII 文字としても表示しようとします。 例: (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._.... |
character | c | バイトを ASCII 文字として表示します。 例: (int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0 |
printable character | C | バイトを印刷可能な ASCII 文字として表示します。 例: (int *) c.sp.x = P.._.... |
complex float | F | この値を、複素数の浮動小数点数の実部および虚部の値と解釈します。 例: (int *) c.sp.x = 2.76658e+19 + 4.59163e-41i |
decimal | d、i | 符号付き整数として表示します(キャストは実行せず、バイトを符号付き整数として表示します)。 |
enumeration | E、en | 列挙値として表示します。値の名前がある場合はその名前を出力し、それ以外の場合は整数値を出力します。 例: (enum enumType) val_type = eValue2 |
hexadecimal - 小文字 | x、h | 小文字の 16 進表記で表示します(キャストは実行せず、バイトを 16 進数として表示します)。 |
hexadecimal - 大文字 | X、H | 大文字の 16 進表記で表示します(キャストは実行せず、バイトを 16 進数として表示します)。 |
hexadecimal - 小文字、先頭の 0x なし | xb、hb | 0x プレフィックスなしの小文字の 16 進表記で表示します(キャストは実行せず、バイトを 16 進数として表示します)。 |
hexadecimal - 大文字、先頭の 0x なし | Xb、Hb | 0x プレフィックスなしの大文字の 16 進表記で表示します(キャストは実行せず、バイトを 16 進数として表示します)。 |
float | f | 浮動小数点数として表示します(キャストは実行せず、バイトを IEEE754 浮動小数点値として解釈します)。 |
octal | o | 8 進表記で表示します。 |
OS type | O | Mac OS の種類として表示します。 例: (float) x = '\n\x1f\xd7\n' |
string - C 文字列 | s | 0 で終わる C 文字列として表示します。 例: "hello world" |
string - C 文字列、引用符なし | sb | 0 で終わる C 文字列として、引用符なしで表示します。 例: hello world |
string - UTF-8 | s8 | 0 で終わる UTF-8 文字列として表示します。 例: u8"hello world ☕" |
string - UTF-8、引用符なし | s8b | 0 で終わる UTF-8 文字列として、引用符なしで表示します。 例: hello world ☕ |
string - UTF-16 | su | 0 で終わる UTF-16 文字列として表示します。 例: u"hello world ☕" |
string - UTF-16、引用符なし | sub | 0 で終わる UTF-16 文字列として、引用符なしで表示します。 例: hello world ☕ |
string - UTF-32 | s32 | 0 で終わる UTF-32 文字列として表示します。 e.g. U"hello world ☕" |
string - UTF-32、引用符なし | s32b | 0 で終わる UTF-32 文字列として、引用符なしで表示します。 hello world ☕ |
unicode16 | U | UTF-16 文字として表示します。 例: (float) x = 0xd70a 0x411f |
unicode32 | U32 | UTF-32 文字として表示します。 例: (float) x = 0x411fd70a |
unsigned decimal | u | 符号なし整数として表示します(キャストは行わず、バイトを符号なし整数として表示します)。 |
pointer | p | ネイティブ ポインタとして表示します(実際にポインタでない場合、生成されるアドレスが無効となる可能性があります)。 |
complex integer | I | この値を複素整数の実部と虚部として解釈します。 例: (int *) pointer = 1048960 + 1i |
character array | a | 文字の配列として表示します。 例: (char) *c.sp.z = {X} |
Raw | ! | RAW 形式で表示し、データ型ビューのカスタマイズは無視します。 |
Natvis
Visual Studio で Natvis フレームワークを使用すると、デバッガの変数ウィンドウでネイティブ型を表示する方法をカスタマイズできます。たとえば、Natvis を使用して、[ウォッチ]、[ローカル]、[データヒント] の各ウィンドウの表示をカスタマイズします。
Natvis 機能はデフォルトで有効になっていますが、Visual Studio で [ツール] > [オプション] > [Android Game Development Extension] > [Natvis] のフラグを [無効] に設定すると無効にできます。
Natvis ファイルの読み込み
Visual Studio は、以下の 3 つの場所から Natvis ファイルを読み込み、デバッグ セッションが開始されるたびにそれらのファイルを再読み込みします。ファイルは Visual Studio 2017 Natvis スキーマを遵守している必要があります。
- 読み込まれたプロジェクトまたは最上位のソリューション アイテムに含まれる
.natvis
ファイル。 - ユーザー固有のディレクトリ(
%USERPROFILE%\Documents\Visual Studio 2017\Visualizers
) - システム全体のディレクトリ(
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers
)
Natvis ファイルの再読み込み
デバッグ セッション中に Natvis ファイルを再読み込みするには、[コマンド ウィンドウ] または [ウォッチ] ウィンドウで .natvisreload
を評価します。
サンプルの Natvis ファイル
サンプルの Natvis ファイルには、現在サポートされているすべてのタグと属性が含まれています。
<?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>
Natvis ファイルの作成
Visual Studio は、独自の Natvis ファイルの作成をサポートしています。詳細情報 デバッガ変数ウィンドウのカスタマイズについては、 MSDN。
Natvis ファイルのデバッグ
[自動変数] ウィンドウや [ウォッチ] ウィンドウなどの変数の [値] としてエラーが表示される場合があります(例: <error: use of undeclared
identifier 'missingVar'>
)。
Android Game Development Extension ツールバーから GoogleAndroid.log
ファイルを開くと、エラーの詳細情報にアクセスできます。
既知の制限事項
上記のサンプル ファイルに記載されていないタグや属性は現在サポートされていません。サポートされていないタグと属性は Visual Studio で無視されるので、それらを既存の Natvis ファイルに残したままでもファイルは機能します(それにはファイルが Natvis スキーマを使用している必要があります)。
Usage
属性はスキーマでは必須とされていますが、<SmartPointer>
ではサポートされていません。ただし、LLDB では C++ で定義された演算子へのアクセスは制限されていないため、必須の演算子を代わりに C++ で定義できます。