Debuger

Debuguj projekt za pomocą Visual Studio Debugger (LLDB), gdy korzystasz z Rozszerzenie Android Game Development.

Uruchamianie debugera

Zanim uruchomisz debuger, musisz być w stanie skompilować, wdrożyć i uruchomić gry na Androida. Więcej informacji znajdziesz w sekcji Uruchamianie przykładu.

Gdy upewnisz się, że grę można uruchomić bez debugera, za pomocą parametru debugera, naciskając F5 lub wybierając element Rozpocznij debugowanie. w menu Debuguj. Podczas podłączania debugera powinno się pojawić okno do gry.

Uruchomienie debugera może potrwać od 10 sekund do 1 minuty w zależności od rozmiaru aplikacji i liczby potrzebnych symboli ładowany podczas uruchamiania. Podłączenie do nowego urządzenia trwa dłużej przez ponieważ debuger musi pobrać niektóre biblioteki Androida z z komputerem hosta. Jeśli podczas pierwszego na nowym urządzeniu, rozważ anulowanie sesji debugowania, a następnie i uruchomię go z powrotem.

Po uruchomieniu debugera w ten sposób gra uruchamia się w trybie Czekam na w trybie debugera. Nie będzie on wykonywać kodu gry do czasu nawiązywane jest połączenie z debugerem. Pozwala to również debugować sekcję inicjowania funkcji Twojej gry.

Więcej informacji o konkretnych funkcjach debugera Visual Studio znajdziesz w tych sekcjach: znajdziesz w dokumentacji Studio Visual Studio.

Dołączanie do procesu

jeśli chcesz debugować grę, która jest już uruchomiona w trybie fizycznym lub wirtualnym; urządzenia, możesz podłączyć debuger do procesu z poziomu Visual Studio.

W Visual Studio upewnij się, że rozwiązanie na Androida jest otwarte, a następnie:

  1. Otwórz menu Debugowanie i wybierz Attach to Process (Dołącz do procesu).
  2. W menu Transport wybierz Android Game Development Extension (Rozszerzenie do tworzenia gier na Androida).
  3. Z menu Kwalifikator wybierz swoje urządzenie z Androidem.
  4. Wybierz proces gry z listy dostępnych procesów kliknij Dołącz.

Dołącz do procesu

Wykonywanie poleceń LLDB.Shell

Gdy sesja debugowania jest aktywna, uruchom polecenie w oknie poleceń Visual Studio Polecenia LLDB.Powłoka.

Format polecenia:

LLDB.Shell [command]

Przykład:

>LLDB.Shell expr myIntVariable = 9
Status:  Success
Output Message:
(int) $2 = 9

Wizualizacja danych

Specyfikatory formatu

Możesz zmienić format wyświetlania wartości w sekcji Auto, Okna Locals, Watch i zmiennych DataTip, korzystając ze specyfikacji formatu.

Specyfikacje formatu znajdują się na końcu wyrażeń. Zaczynają się od przecinka, a po nim krótki ciąg znaków. Na przykład specyfikator ,x w parametrze _myInt,x wyrażenie będzie formatować myInt jako małe litery szesnastkowe.

Specyfikacji formatu można użyć bezpośrednio w oknie Obejrzyj lub Autos, Locals i DataTip, dodając je do Natvis wyrażeń. Więcej informacji znajdziesz na stronie Natvis.

Lista specyfikacji pomocy

Nazwa formatu Specyfikatory Opis
Wartość logiczna B pokaż to jako wartość logiczną prawda/fałsz, używając niestandardowej reguły, w której wartość 0 to fałsz, a wszystkie pozostałe wartości są prawdziwe
plik binarny B pokaż to jako sekwencję bitów,
binarny, brak początkowego 0b bb pokaż to jako sekwencję bitów bez prefiksu 0b
B Y ale staraj się wyświetlać je również w postaci znaków ASCII
np. (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._....
bajty z ASCII Y ale staraj się wyświetlać je również w postaci znaków ASCII
np. (int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._....
znak C wyświetlać bajty jako znaki ASCII
np. (int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0
znak do druku C pokazują bajty jako możliwe do wydrukowania znaki ASCII
np. (int *) c.sp.x = P.._....
złożona liczba zmiennoprzecinkowa F zinterpretuj tę wartość jako prawdziwą i urojoną część złożonej liczby zmiennoprzecinkowej,
np. (int *) c.sp.x = 2.76658e+19 + 4.59163e-41i
separator dziesiętny d, i pokaż to jako liczbę całkowitą ze znakiem (nie jest to rzutowanie, a jedynie wyświetlane bajty w postaci liczby całkowitej ze znakiem).
wyliczenie E,ang. pokaż to jako wyliczenie, drukując nazwę wartości, jeśli jest dostępna, lub w innym przypadku wartość będącą liczbą całkowitą.
np. (typ wyliczenia) val_type = eValue2
szesnastkowy – małe litery x, wys pokaż to w notacji szesnastkowej małymi literami (nie jest to rzutowanie, ale wyświetlane są bajty w postaci szesnastkowej)
szesnastkowy system szesnastkowy (wielkie litery) X, H pokaż to w notacji szesnastkowej wielkimi literami (nie jest to rzutowanie, ale wyświetlane są bajty w postaci szesnastkowej)
szesnastkowy system liczbowy – małe litery, bez poprzedzającego 0x xb, HB pokaż to w notacji szesnastkowej pisane małymi literami bez prefiksu 0x (nie jest to rzutowanie, a jedynie wyświetlane bajty w postaci szesnastkowej)
szesnastkowy system liczbowy – duże litery, bez początkowego 0x Xb, Hb pokaż to w notacji szesnastkowej pisanej wielkimi literami bez prefiksu 0x (nie jest to rzutowanie, tylko wyświetla bajty jako wartości szesnastkowe)
liczba zmiennoprzecinkowa F pokaż to jako liczbę zmiennoprzecinkową (nie przeprowadza to rzutowania, tylko interpretuje bajty jako wartość zmiennoprzecinkową IEEE754).
ósemkowy o pokaż to w zapisie ósemkowym
Typ systemu operacyjnego O jest to typ systemu operacyjnego MacOS,
np. (liczba zmiennoprzecinkowa) x = '\n\x1f\xd7\n'
string – C-string s pokaż to jako ciąg znaków C z zakończeniem 0
np. „witaj świecie”
string – ciąg znaków C, bez cudzysłowów. sb jako ciąg znaków C z zakończeniem 0 bez cudzysłowów,
np. witaj świecie
ciąg znaków – UTF-8 S8 jako ciąg znaków UTF-8 z zakończeniem 0
np. u8"witaj świecie ☕"
ciąg znaków – UTF-8, bez cudzysłowów; S8B pokaż to jako ciąg UTF-8 z zakończeniem 0 bez cudzysłowu.
np. witaj świecie ☕
ciąg znaków – UTF-16 nd. pokaż to jako ciąg znaków UTF-16 z zakończeniem 0
np. u"witaj świecie ☕"
ciąg znaków – UTF-16, bez cudzysłowów; subskrypcja pokaż to jako ciąg UTF-16 z zakończeniem 0, bez cudzysłowów.
np. witaj świecie ☕
ciąg znaków – UTF-32 S32 jako ciąg znaków UTF-32 z zakończeniem 0
np. "Witaj świecie ☕"
ciąg znaków – UTF-32, bez cudzysłowów; S32B pokaż to jako ciąg UTF-32 z zakończeniem 0, bez cudzysłowów.
np. witaj świecie ☕
kod unicode16 U pokaż to jako znaki UTF-16.
np. (liczba zmiennoprzecinkowa) x = 0xd70a 0x411f
kod unicode32 U32 pokaż to jako znaki UTF-32.
np. (liczba zmiennoprzecinkowa) x = 0x411fd70a
liczba dziesiętna bez znaku U pokaż to jako niepodpisaną liczbę całkowitą (nie powoduje to rzutowania, ale wyświetlane bajty jako niepodpisana liczba całkowita)
wskaźnik P pokaż to jako natywny wskaźnik (chyba że jest to naprawdę wskaźnik, wynikowy adres będzie prawdopodobnie nieprawidłowy)
zespolona liczba całkowita I zinterpretuj tę wartość jako prawdziwą i urojoną część złożonej liczby całkowitej,
np. (int *) wskaźnik = 1048960 + 1i
tablica znaków a pokaż to w postaci tablicy znaków
np. (znak) *c.sp.z = {X}
Nieprzetworzony ! format nieprzetworzony, ignorowanie wszelkich dostosowań widoków typów danych

Natvis

Platforma Natvis umożliwia dostosowanie sposobu wyświetlania zawartości do Visual Studio. natywne w oknach zmiennych debugera. Użyj na przykład Natvis, aby dostosować ekrany w oknach Watch, Locals i Data Guidelines (Wskazówki dotyczące danych).

Funkcja Natvis jest domyślnie włączona, ale można ją wyłączyć w Visual Studio przez ustawienie menu Narzędzia > Opcje > Rozszerzenie Android Game Development > Natvis ustaw na Wyłączono.

Wczytuję pliki Natvis

Visual Studio wczytuje pliki Natvis z 3 lokalizacji wymienionych poniżej, ładują się ponownie po każdym rozpoczęciu sesji debugowania. Pliki muszą być zgodne z Schemat Visual Studio 2017 Natvis.

  • .natvis pliki, które są częścią wczytanego projektu lub elementu rozwiązania najwyższego poziomu.
  • W katalogu specyficznym dla użytkownika (%USERPROFILE%\Documents\Visual Studio 2017\Visualizers)
  • W katalogu systemowym (%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers)
Ponownie ładuję pliki Natvis

Załaduj ponownie pliki Natvis podczas sesji debugowania, oceniając .natvisreload w Okno poleceń lub Watch.

Przykładowy plik Natvis

Ten przykładowy plik Natvis zawiera wszystkie tagi i atrybuty obsługiwane.

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

  <Type Name="demo::Vector&lt;*&gt;">
    <AlternativeType Name="MySimilarVectorType&lt;*&gt;"/>

    <!-- 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 &lt; 4 &amp;&amp; _size &gt;= 1" Optional="true">_items[0]</Item>
      <Item Name="Y" Condition="_size &lt; 4 &amp;&amp; _size &gt;= 2" Optional="true">_items[1]</Item>
      <Item Name="Z" Condition="_size &lt; 4 &amp;&amp; _size &gt;= 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>

Tworzenie plików Natvis

Visual Studio umożliwia tworzenie własnych plików Natvis. Więcej informacji na temat konfiguracji o dostosowywaniu okien zmiennych debugera znajdziesz w artykule MSDN.

Debugowanie plików Natvis

W niektórych przypadkach błędy będą przedstawiane jako Wartość zmiennej (np. w polu Auto, Zegarek itp.). Przykład: <error: use of undeclared identifier 'missingVar'>

Aby uzyskać więcej informacji o błędzie, otwórz GoogleAndroid.log na pasku narzędzi rozszerzenia Android Game Development Extension.

Znane ograniczenia

  • Jeśli Twojego tagu lub atrybutu nie ma na liście w przykładowym pliku powyżej, nie są obecnie obsługiwane. Visual Studio ignoruje nieobsługiwane tagi i atrybuty, więc możesz zostawić je w istniejącym pliku Natvis. Plik będzie działać, korzysta z naszego schematu.

  • Atrybut Usage, choć jest wymagany przez schemat, nie jest obsługiwany w przypadku <SmartPointer> LLDB nie ogranicza jednak dostępu do operatorów w języku C++, tak aby dowolny wymagany operator można było zdefiniować w C++.