Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ve verzi 10.0.25310.1001 a novějších ladicího modulu je nyní podporováno řešení nejednoznačných zarážek.
Nejednoznačné zarážky umožňují ladicímu programu nastavit zarážky v určitých scénářích, kdy se výraz zarážky vyřeší na více míst. K tomu může dojít například v těchto případech:
- Více přetížení funkce.
- Existuje několik symbolů, které odpovídají výrazu zarážky.
- Stejný název symbolu se používá pro více umístění.
- Symbol byl vložen.
- Nastavení bodu přerušení ve funkci šablony s několika instancemi v okně zdroje.
Pokud je tato možnost povolená, ladicí program nastaví zarážku pro každou shodu symbolů pro daný výraz zarážky. Ladicí program bude také filtrovat odpovídající symboly, pokud jsou splněna určitá kritéria.
Obecné informace o používání zarážek naleznete v tématu Použití zarážek.
Povolení nejednoznačného rozlišování bodu zlomu
Ve výchozím nastavení jsou nejednoznačné body přerušení zakázané. Pokud to chcete povolit v relaci ladicího programu, spusťte tento příkaz v konzole WinDbg:
dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true;
Pro ověření, že je nastavení nejednoznačných zarážek aktivní:
0:010> dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints
@$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints : true
Další informace o použití příkazu dx naleznete v tématu dx (Display Debugger Object Model Expression).
Chcete-li tuto funkci zakázat, nastavte výše uvedenou hodnotu falsena hodnotu . Chcete-li zajistit, aby nastavení přetrvávalo napříč relacemi, nezapomeňte kliknout na File -> Settings -> Debugger Settings a zaškrtnout políčko označené Persist engine settings across debugger sessions.
Použití se vztahuje na jednotlivé breakpointy.
Řešení nejednoznačných výrazů bodů přerušení se vztahuje pouze na použití příkazu pro nastavení jednoho bodu přerušení v debuggeru. Jinými slovy, nastavení více bodů přerušení pomocí příkazu bm bude fungovat jako obvykle. Spuštění příkazu s povolenou funkcí způsobí nové chování zarážek pro jednotlivé zarážky.
Obecné informace o zarážkových příkazech naleznete v tématu bp, bu, bm (Set Breakpoint).
Hierarchické zarážky
Hierarchické zarážky představují výsledek překladu nejednoznačného výrazu zarážky na více zarážek. Pokud výsledkem výrazu jsou dvě nebo více shod, které se použijí k nastavení zarážek, vytvoří se další zarážka, která bude řídit sadu zarážek. Tato přepsaná zarážka, hierarchická zarážka, může být povolena, zakázána nebo smazána a zobrazena jako běžná zarážka. Má však přidanou funkci, která umožňuje provádět to samé na zarážkách, které vlastní.
Pokud je například příkaz bp foo!bar spuštěn, výsledkem jsou dvě shody se symbolem bar, vytvoří se hierarchická zarážka, která řídí obě shody. Pokud je hierarchická funkce povolena, zakázána nebo vymazána, tak se také shodí s odpovídajícími body přerušení.
Příkaz .bpcmds(Display Breakpoint Commands) zobrazí příkaz zarážky, který lze spustit a nastavit každou zarážku. Zarážky, které patří pod hierarchickou zarážku, budou dál vypisovat platný příkaz bp, který nastaví zarážku na její adrese. Hierarchické zarážky budou také uvedeny ve výstupu a zobrazí příkaz, který se dá použít k opětovnému vytvoření celé sady zarážek místo jediné zarážky.
Nejednoznačné symboly
Nastavení zarážky u názvu symbolu by mělo mít za následek následující chování, pokud je symbol:
Přetížení: Každé přetížení, které odpovídá symbolu, by mělo mít bod přerušení.
Funkce šablony:
Pokud má výraz zadané všechny parametry šablony (například
bp foo!bar<int>), nastaví se zarážka pro konkrétní implementaci funkce šablony.Pokud výraz nemá zadanou implementaci typu (například
bp foo!bar), nenastaví se žádné body přerušení. V tomto případě by se mělobmpoužít k nastavení zarážek u funkce šablony.Ladicí program nepodporuje částečné specifikace šablon, a proto v tomto případě nebudou nastavena žádná přerušení.
Vložená funkce: Každé místo, kde je funkce vložena, má bod přerušení.
Všimněte si, že pokud výraz symbolu obsahuje operátory nebo posuny, které vyžadují větší vyhodnocení ladicím programem, nebude nastaveno více zarážek. Pokud se například symbol foo vyhodnotí na více míst, ale výraz foo+5 je zpracován, ladicí program se nepokusí nastavit zarážky na všech těchto místech.
Příklady kódu breakpointů
Vzhledem k následujícímu fragmentu kódu:
class BikeCatalog
{
public:
void GetNumberOfBikes()
{
std::cout << "There are 42 bikes." << std::endl;
}
int GetNumberOfBikes(int num)
{
std::cout << "There are " << num << " bikes." << std::endl;
return num;
}
};
Vyvolání příkazu bu BikeCatalog::GetNumberOfBikes by vedlo k vytvoření dvou zarážek, jedné pro každé přetížení. Výpis zarážek by vedlo k následujícímu výstupu:
0:000> bl
2 e Disable Clear <hierarchical breakpoint> 0001 (0001) 0:**** {BikeCatalog!BikeCatalog::GetNumberOfBikes}
0 e Disable Clear 00007ff6`c6f52200 [C:\BikeCatalog\BikeCatalog.cpp @ 13] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
1 e Disable Clear 00007ff6`c6f522a0 [C:\BikeCatalog\BikeCatalog.cpp @ 9] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
Nejednoznačné zdrojové řádky
Nastavení bodu přerušení na zdrojovém řádku by mělo mít následující chování, pokud je zdrojový řádek:
- Funkce optimalizovaná kompilátorem: Pokud je řádek rozdělený do více umístění kvůli optimalizaci kompilátoru, nastaví se zarážka na nejnižším místě v rámci funkce odpovídající zadanému řádku.
- Vložená funkce: Pro každou lokalitu volání je nastavena zarážka, pokud není zadaný řádek optimalizovaný jako součást vkládání.
- Vyřešeno na více umístění: Pokud výše uvedené podmínky nejsou splněny, pro každou adresu se nastaví zarážka s následujícími podmínkami:
- Pokud existuje sada N adres, které odpovídají zdrojovému řádku ve výrazu, a podmnožina M těchto N adres má nulový posun řádku zdroje ze zdrojového řádku ve výrazu, pak budou mít zarážky pouze adresy M .
- Pokud v sadě N adres nejsou žádné adresy, které mají nulový posun řádku zdroje ze zdrojového řádku ve výrazu, budou mít všechny N adresy zarážky.
Filtrování na základě indexu symbolů
Každý symbol by měl mít jedinečný index symbolů. Podrobné informace o struktuře symbolů najdete v tématu SYMBOL_INFO struktura.
Ladicí program použije index symbolů k tomu, aby se v případě více adres s nulovým přesunutím řádku zdroje vyfiltrovaly duplicitní shody.
Příklady funkcí šablon a přetížených funkcí
Funkce šablon
Nastavení zarážky na zdrojovém řádku pro definici funkce šablony způsobí zarážku pro každou implementaci funkce šablony. S ohledem na následující funkci šablony na řádku 19:BikeCatalog.cpp
template <class T>
void RegisterBike(T id)
{
std::cout << "Registered bike " << id << std::endl;
}
A jeho využití:
catalog.RegisterBike("gravel bike");
catalog.RegisterBike(1234);
Vyvolání příkazu bp `BikeCatalog.cpp:19` nastaví dva body přerušení, které odpovídají implementacím funkce šablony, jež se použijí později v souboru. Pokud by uživatel chtěl u funkce nastavit jednu zarážku, musel by buď nastavit zarážku na konkrétním zdrojovém řádku implementace funkce šablony, nebo nastavit zarážku na symbol funkce šablony s odpovídajícími informacemi o typu (např. bp BikeCatalog::RegisterBike<int>).
Výpis zarážek vede k následujícímu výstupu:
0:000> bl
2 e Disable Clear <hierarchical breakpoint> 0001 (0001) 0:**** {BikeCatalog!BikeCatalog::RegisterBike<int>}
0 e Disable Clear 00007ff7`6b691dd0 [C:\BikeCatalog\BikeCatalog.cpp @ 20] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::RegisterBike<int>
1 e Disable Clear 00007ff7`6b691e60 [C:\BikeCatalog\BikeCatalog.cpp @ 20] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::RegisterBike<char const *>
Přetížené funkce
Nastavení zarážky na zdrojovém řádku pro definici přetížené funkce způsobí, že v této definici přetížené funkce bude jenom jedna zarážka. Opětovné spuštění fragmentu kódu z výše uvedeného řádku s prvním řádkem začínajícím na řádku 5:
class BikeCatalog
{
public:
void GetNumberOfBikes()
{
std::cout << "There are 42 bikes." << std::endl;
}
int GetNumberOfBikes(int num)
{
std::cout << "There are " << num << " bikes." << std::endl;
return num;
}
};
Vyvolání příkazu bp `BikeCatalog.cpp:9` nastaví v řádku jeden bod přerušení pro void implementaci GetNumberOfBikes. Výpis zarážek vede k následujícímu výstupu:
0:000> bl
0 e Disable Clear 00007ff7`6b691ec0 [C:\BikeCatalog\BikeCatalog.cpp @ 9] 0001 (0001) 0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
vložené funkce
Nastavení zarážky na zdrojovém řádku pro místo volání vložené funkce bude mít za následek pouze jednu zarážku na tomto konkrétním místě volání, i když je ve stejné funkci přítomno jiné místo volání.
Několik hierarchických zarážek
Hierarchické zarážky vlastní každou zarážku v sadě, pokud ne:
Zarážka v sadě se vymaže.
- Hierarchická zarážka se vymaže.
- Vytvoří se další hierarchická zarážka, která obsahuje zarážku v sadě hierarchických zarážek.
Dalším způsobem, jak si to představit, je, že zarážky můžou mít pouze jednoho hierarchického vlastníka zarážky a že poslední příkaz zarážky určí, jaký má být stav seznamu zarážek.
Hierarchický zlom navíc nemůže vlastnit jiný hierarchický zlom.
Včlenění předem existujících zarážek
Pokud zarážka A existuje samostatně a pak se nejednoznačný výraz zarážky vyřeší k vytvoření zarážek A, B, pak bude A zahrnuta do nové sady zarážek s B.
Pohlcující hierarchické průsečíky množin zarážek
Pokud hierarchická zarážka A vlastní zarážky B, C a nejednoznačný výraz zarážky je vyřešen k vytvoření zarážek:
B, C, D: Zarážky B, C připojí novou hierarchickou skupinu zarážek s zarážkou D a hierarchická zarážka A se vymaže.
C, D nebo B, D: Jedna ze zarážek se připojí k nové hierarchické skupině zarážek s zarážkou D a hierarchická zarážka A bude nadále existovat s jednou zbývající zarážkou, která se nepřipojila k nové skupině.