Wyrażenia w debugerze programu Visual Studio

Debuger programu Visual Studio zawiera ewaluatory wyrażeń, które działają podczas wprowadzania wyrażenia w oknie dialogowym QuickWatch, oknie Watch lub bezpośrednim oknie. Ewaluatory wyrażeń działają również w oknie Punkty przerwania i wiele innych miejsc w debugerze.

W poniższych sekcjach opisano ograniczenia oceny wyrażeń dla języków obsługiwanych przez program Visual Studio.

Wyrażenia języka F# nie są obsługiwane

Wyrażenia języka F# nie są rozpoznawane. Jeśli debugujesz kod języka F#, musisz przetłumaczyć wyrażenia na składnię języka C# przed wprowadzeniem wyrażeń do okna debugera lub okna dialogowego. Podczas tłumaczenia wyrażeń z języka F# na język C#pamiętaj, że język C# używa == operatora do testowania pod kątem równości, podczas gdy język F# używa pojedynczego =elementu .

Wyrażenia języka C++

Aby uzyskać informacje na temat używania operatorów kontekstu z wyrażeniami w języku C++, zobacz Operator kontekstu (C++).

Nieobsługiwane wyrażenia w języku C++

Konstruktory, destruktory i konwersje

Nie można wywołać konstruktora ani destruktora dla obiektu jawnie lub niejawnie. Na przykład następujące wyrażenie jawnie wywołuje konstruktor i powoduje wyświetlenie komunikatu o błędzie:

my_date( 2, 3, 1985 )

Nie można wywołać funkcji konwersji, jeśli miejscem docelowym konwersji jest klasa. Taka konwersja obejmuje konstrukcję obiektu. Jeśli na przykład myFraction jest wystąpieniem CFractionklasy , które definiuje operator FixedPointfunkcji konwersji, następujące wyrażenie powoduje błąd:

(FixedPoint)myFraction

Nie można wywołać nowych ani usuniętych operatorów. Na przykład następujące wyrażenie nie jest obsługiwane:

new Date(2,3,1985)

Makra preprocesora

Makra preprocesora nie są obsługiwane w debugerze. Jeśli na przykład stała VALUE jest zadeklarowana jako: #define VALUE 3, nie można jej użyć VALUE w oknie Czujka . Aby uniknąć tego ograniczenia, należy zastąpić #defineciągi "s wyliczeniami i funkcjami zawsze, gdy jest to możliwe.

używanie deklaracji przestrzeni nazw

Nie można używać using namespace deklaracji. Aby uzyskać dostęp do nazwy typu lub zmiennej poza bieżącą przestrzenią nazw, należy użyć w pełni kwalifikowanej nazwy.

Anonimowe przestrzenie nazw

Anonimowe przestrzenie nazw nie są obsługiwane. Jeśli masz następujący kod, nie możesz dodać test go do okna zegarka:

namespace mars
{
    namespace
    {
        int test = 0;
    }
}
int main()
{
    // Adding a watch on test doesn't work.
    mars::test++;
    return 0;
}

Używanie funkcji wewnętrznych debugera do zachowania stanu

Funkcje wewnętrzne debugera umożliwiają wywoływanie niektórych funkcji języka C/C++ w wyrażeniach bez zmieniania stanu aplikacji.

Funkcje wewnętrzne debugera:

  • Gwarantowane jest bezpieczeństwo: wykonywanie funkcji wewnętrznej debugera nie spowoduje uszkodzenia procesu, który jest debugowany.

  • Są dozwolone we wszystkich wyrażeniach, nawet w scenariuszach, w których skutki uboczne i ocena funkcji nie są dozwolone.

  • Praca w scenariuszach, w których zwykłe wywołania funkcji nie są możliwe, takie jak debugowanie minidump.

    Funkcje wewnętrzne debugera mogą również ułatwić ocenianie wyrażeń. Na przykład strncmp(str, "asd") znacznie łatwiej jest zapisywać w warunku punktu przerwania niż str[0] == 'a' && str[1] == 's' && str[2] == 'd'. )

Obszar Funkcje wewnętrzne
Długość ciągu strlen, wcslen, strnlen, wcsnlen
Porównanie ciągów strcmp, wcscmp, stricmp, wcsicmp, _stricmp, _strcmpi, _wcsicmp, _wcscmpi, strncmp, wcsncmp, strnicmp, wcsnicmp, _strnicmp, _wcsnicmp
Wyszukiwanie ciągów strchr, wcschr, memchr, wmemchr, strstr, wcsstr
Win32 CoDecodeProxy, DecodePointer, GetLastError, TlsGetValue
Windows 8 RoInspectCapturedStackBackTrace, WindowsCompareStringOrdinal, WindowsGetStringLen, WindowsGetStringRawBuffer

Te funkcje wymagają debugowania procesu, który ma być uruchomiony w systemie Windows 8. Debugowanie plików zrzutu generowanych na urządzeniu z systemem Windows 8 wymaga również, aby komputer programu Visual Studio był uruchomiony w systemie Windows 8. Jeśli jednak debugujesz zdalnie urządzenie z systemem Windows 8, komputer programu Visual Studio może działać z systemem Windows 7.
WindowsGetStringLen i WindowsGetStringRawBuffer są używane tylko przez aparat wykonywania (EE) na poziomie źródłowym.
Różne __log2 — zwraca bazę dziennika 2 określonej liczby całkowitej zaokrąglonej do najbliższej dolnej liczby całkowitej.

__findNonNull — wyszukuje tablicę wskaźników, zwracając indeks pierwszego elementu innego niż null.
- Parametry: (1) Wskaźnik do pierwszego elementu w tablicy (void*), (2) Rozmiar tablicy (bez znaku int).
- Wartości zwracane: (1) 0- oparty na indeksie pierwszego elementu innego niż null w tablicy lub -1, jeśli nie zostanie znaleziony.

DecodeHString — funkcja pomocnika służąca do formatowania wartości HSTRING. Umieszcza wartość HSTRING poza stosem, wypycha bajty struktury StringInfo, której EE może użyć, aby określić, gdzie znajduje się ciąg. Jest to używane tylko wewnętrznie przez EE; Nie jest on dostępny dla użytkownika do bezpośredniego wywołania.

DecodeWinRTRestrictedException — dekoduje wyjątek z ograniczeniami WinRT, aby uzyskać ograniczony opis.
- Parametry: (1) znaki ciągu zakończonego wartością null reprezentującego ograniczony ciąg odwołania.
- Wartość zwracana: Znaki ciągu zakończonego wartością null zawierającego rzeczywisty komunikat o błędzie do pokazania.

DynamicCast — implementuje dynamic_cast.
- Parametry: (1) Wskaźnik do obiektu do rzutowania.
- Elementy danych: obiekt CDynamicCastData powinien być skojarzony jako element danych z odpowiednią instrukcją ExecuteIntrinsic(). Element danych koduje typ, z i do, a także określa, czy oceniamy wyrażenie natvis (potrzebne do diagnostyki w celu przerwania nieskończonej rekursji).
- Wartość zwracana: (1) Wskaźnik do obiektu, rzutowanie do poprawnego typu lub wartość NULL, jeśli rzutowanie obiektu nie jest wystąpieniem poprawnego typu.

DynamicMemberLookup — funkcja pomocnika, która dynamicznie pobiera wartość składowej klasy

GetEnvBlockLength — funkcja pomocnika, aby uzyskać długość bloku środowiska w postaci znaków. Służy do $env.

Stdext_HashMap_Int_OperatorBracket_idx — Operator[] dla parametru stdext::hash_map. Zakłada domyślną funkcję skrótu z kluczem "int". Zwraca wartość. Operator wewnętrzny[] obsługuje tylko pobieranie istniejących elementów z tabeli skrótów — nie obsługuje wstawiania nowych elementów do tabeli, ponieważ może to wiązać się z niechcianymi złożonościami, takimi jak alokacja pamięci. Jednak operator[] może służyć do modyfikowania wartości skojarzonej z kluczem już w tabeli.
- Parametry stosu: (1) Adres obiektu stdext::hash_map, (2) Klucz do tabeli (int), (3) struktura HashMapPdb określająca przesunięcia pól składowych, których implementacja funkcji musi wykonać wyszukiwanie. Jest to wymagane, ponieważ bezpośredni dostęp do symboli nie jest dostępny po stronie zdalnej.
- Zwracane wartości: (1) Jeśli klucz znajduje się w tabeli, adres wartości odpowiadającej kluczowi. W przeciwnym razie wartość NULL.

Std_UnorderedMap_Int_OperatorBracket_idx — std::unordered_map działa tak samo jak stdext::hash_map, z wyjątkiem funkcji skrótu jest inna.

ConcurrencyArray_OperatorBracket_idx // Concurrency::array<>::operator[index<>] i operator(index<>)

ConcurrencyArray_OperatorBracket_int // Concurrency::array<>::operator(int, int, ...)

ConcurrencyArray_OperatorBracket_tidx // Concurrency::array<>:operator[tiled_index<>] i operator(tiled_index<>)

ConcurrencyArrayView_OperatorBracket_idx // Concurrency::array_view<>::operator[index<>] i operator(index<>)

ConcurrencyArrayView_OperatorBracket_int // Concurrency::array_view<>::operator(int, int, ...)

ConcurrencyArrayView_OperatorBracket_tidx // Concurrency::array_view<>::operator[tiled_index<>] i operator(tiled_index<>)

TreeTraverse_Init — inicjuje nowe przechodzenie drzewa.
Obsługuje wizualizatory oparte na rozszerzeniach, które nie mają być używane w plikach natvis .

TreeTraverse_Next — pobiera węzły z oczekującego przejścia drzewa.
Obsługuje wizualizatory oparte na rozszerzeniach, które nie mają być używane w plikach natvis .

TreeTraverse_Skip — pomija węzły w oczekującym przechodzeniu drzewa.
Obsługuje wizualizatory oparte na rozszerzeniach, które nie mają być używane w plikach natvis .

C++/CLI — nieobsługiwane wyrażenia

  • Rzuty obejmujące wskaźniki lub rzuty zdefiniowane przez użytkownika nie są obsługiwane.

  • Porównanie obiektów i przypisanie nie są obsługiwane.

  • Przeciążone operatory i przeciążone funkcje nie są obsługiwane.

  • Obsługa boksu i rozpałkania nie jest obsługiwana.

  • Sizeof operator nie jest obsługiwany.

C# — nieobsługiwane wyrażenia

Obiekty dynamiczne

Zmienne można używać w wyrażeniach debugera, które są statycznie wpisywane jako dynamiczne. Gdy obiekty implementujące IDynamicMetaObjectProvider są oceniane w oknie Obserwowanie, dodawany jest węzeł Widok dynamiczny. Węzeł Widok dynamiczny zawiera elementy członkowskie obiektów, ale nie zezwala na edytowanie wartości elementów członkowskich.

Następujące funkcje obiektów dynamicznych nie są obsługiwane:

  • Operatory +=złożone , , %=-=, /=i*=

  • Wiele rzutów, w tym rzutów liczbowych i rzutów typu

  • Wywołania metody z więcej niż dwoma argumentami

  • Metody pobierania właściwości z więcej niż dwoma argumentami

  • Zestawy właściwości z argumentami

  • Przypisywanie do indeksatora

  • Operatory && logiczne i ||

Metody anonimowe

Tworzenie nowych metod anonimowych nie jest obsługiwane.

Visual Basic — nieobsługiwane wyrażenia

Obiekty dynamiczne

Zmienne można używać w wyrażeniach debugera, które są statycznie wpisywane jako dynamiczne. Gdy obiekty implementujące IDynamicMetaObjectProvider obiekt są oceniane w oknie Obserwowanie, dodawany jest węzeł Widok dynamiczny. Węzeł Widok dynamiczny zawiera elementy członkowskie obiektów, ale nie zezwala na edytowanie wartości elementów członkowskich.

Następujące funkcje obiektów dynamicznych nie są obsługiwane:

  • Operatory +=złożone , , %=-=, /=i*=

  • Wiele rzutów, w tym rzutów liczbowych i rzutów typu

  • Wywołania metody z więcej niż dwoma argumentami

  • Metody pobierania właściwości z więcej niż dwoma argumentami

  • Zestawy właściwości z argumentami

  • Przypisywanie do indeksatora

  • Operatory && logiczne i ||

Stałe lokalne

Stałe lokalne nie są obsługiwane.

Importowanie aliasów

Aliasy importu nie są obsługiwane.

Deklaracje zmiennych

Nie można zadeklarować jawnych nowych zmiennych w oknach debugera. Można jednak przypisać nowe niejawne zmienne wewnątrz okna natychmiastowego. Te niejawne zmienne są ograniczone do sesji debugowania i nie są dostępne poza debugerem. Na przykład instrukcja o = 5 niejawnie tworzy nową zmienną o i przypisuje do niej wartość 5. Takie niejawne zmienne są typu Object , chyba że typ może zostać wywnioskowany przez debuger.

Nieobsługiwane słowa kluczowe

  • AddressOf

  • End

  • Error

  • Exit

  • Goto

  • On Error

  • Resume

  • Return

  • Select/Case

  • Stop

  • SyncLock

  • Throw

  • Try/Catch/Finally

  • With

  • Słowa kluczowe na poziomie przestrzeni nazw lub modułu, takie jak End Sub lub Module.