Dela via


Tvetydig lösning för brytpunkter

I version 10.0.25310.1001 och senare av felsökningsmotorn stöds nu tvetydig brytpunktsupplösning.

Tvetydiga brytpunkter gör det möjligt för felsökaren att ange brytpunkter i vissa scenarier där ett brytpunktsuttryck löser sig till flera platser. Detta kan till exempel inträffa när:

  • Flera överbelastningar av en funktion.
  • Det finns flera symboler som matchar ett brytpunktsuttryck.
  • Samma symbolnamn används för flera platser.
  • Symbolen har infogats.
  • Ange en brytpunkt i en mallfunktion med flera instansieringar i källfönstret.

När det är aktiverat anger felsökningsprogrammet en brytpunkt för varje symbolmatchning för ett visst brytpunktsuttryck. Felsökningsprogrammet filtrerar även symbolmatchningar om vissa villkor uppfylls.

Allmän information om hur du använder brytpunkter finns i Använda brytpunkter.

Möjliggöra tvetydig brytpunktslösning

Som standard inaktiveras tvetydiga brytpunkter. Om du vill aktivera detta i en felsökningssession kör du det här kommandot i WinDbg-konsolen:

dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true;

Bekräfta att inställningen för tvetydiga brytpunkter är aktiv:

0:010> dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints
@$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints                 : true

Mer information om hur du använder dx-kommandot finns i dx (Visa objektmodelluttryck för felsökningsprogram).

Om du vill inaktivera funktionen anger du värdet ovan till false. Se till att inställningen bevaras mellan sessioner genom att klicka på File -> Settings -> Debugger Settings och markera sedan kryssrutan markerad Persist engine settings across debugger sessions.

Tillämpning gäller för enskilda brytpunkter

Att lösa tvetydiga brytpunktsuttryck gäller endast för körning av brytpunktskommandot för att ange en enda brytpunkt i felsökningsprogrammet. Med andra ord fortsätter inställningen av flera brytpunkter med bm kommandot att fungera som vanligt. Om du kör kommandot med den här funktionen aktiverad resulterar det i ett nytt brytpunktsbeteende för enskilda brytpunkter.

Allmän information om brytpunktskommandona finns i bp, bu, bm (Ange brytpunkt).

Hierarkiska brytpunkter

Hierarkiska brytpunkter representerar resultatet av att lösa ett tvetydigt brytpunktsuttryck med flera brytpunkter. Om ett uttryck resulterar i två eller flera matchningar som ska användas för att ange brytpunkter skapas en annan brytpunkt som styr brytpunktsuppsättningen. Den här övergripande brytpunkten, den hierarkiska brytpunkten, kan aktiveras/inaktiveras/rensas och visas precis som en normal brytpunkt, med den tillagda funktionen att utföra samma åtgärd på de brytpunkter som den äger.

Om kommandot bp foo!bar till exempel körs, vilket resulterar i två matchningar mot symbolen bar, skapas en hierarkisk brytpunkt som styr de två matchningarna. Om hierarkin är aktiverad/inaktiverad/rensad kommer även de matchade brytpunkterna att påverkas.

.bpcmds(Visa brytpunktskommandon) visar det brytpunktskommando som kan köras för att ange varje brytpunkt. Brytpunkter som ägs av en hierarkisk brytpunkt visar fortfarande ett giltigt bp-kommando som anger en brytpunkt för dess adress. Hierarkiska brytpunkter visas också i utdata och visar kommandot som kan användas för att återskapa hela uppsättningen brytpunkter i stället för bara en enda brytpunkt.

Tvetydiga symboler

Om du anger en brytpunkt för ett symbolnamn bör följande beteende uppstå om symbolen är:

  • En överbelastning: Varje överbelastning som matchar symbolen ska ha en brytpunkt.

  • En mallfunktion:

    • Om uttrycket har alla mallparametrar angivna (till exempel bp foo!bar<int>) anges en brytpunkt för den specifika implementeringen av mallfunktionen.

    • Om uttrycket inte har angett någon typimplementering (till exempel bp foo!bar) anges inga brytpunkter. I det här fallet bm ska användas för att ange brytpunkter i mallfunktionen.

    • Partiella mallspecifikationer stöds inte av felsökningsprogrammet och inga brytpunkter anges i så fall.

  • En inlinad funktion: Varje inlinad position har en brytpunkt

Observera att flera brytpunkter inte anges när symboluttrycket innehåller operatorer eller förskjutningar som kräver mer utvärdering av felsökningsprogrammet. Om symbolen foo till exempel löses upp i flera platser men uttrycket foo+5 utvärderas, kommer felsökaren inte att försöka lösa upp alla platser för att aktivera brytpunkter.

Exempel på brytpunktskod

Med följande kodfragment:

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;
    }
}; 

Om kommandot bu BikeCatalog::GetNumberOfBikes anropas skapas två brytpunkter, en för varje överlagring. En lista över brytpunkterna skulle resultera i följande utdata:

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

Tvetydiga källrader

Om du anger en brytpunkt på en källrad bör följande beteende uppstå om källraden är:

  • En kompilatoroptimerad funktion: Om raden delas på flera platser på grund av kompilatoroptimeringar anges en brytpunkt på den lägsta platsen i funktionen som motsvarar den angivna raden.
  • En inlinjead funktion: En brytpunkt anges för var och en av anropsplatserna, om inte den angivna raden har optimerats bort som en del av inlinjering.
  • Löst till flera platser: Om ovanstående villkor inte uppfylls anges en brytpunkt för varje adress med följande villkor:
    • Om det finns en uppsättning N-adresser som matchar källraden i uttrycket, och en delmängd M av dessa N-adresser har noll källradsförskjutning från källraden i uttrycket, kommer endast M-adresserna att ha brytpunkter.
    • Om det inte finns några adresser i uppsättningen med N-adresser som har noll källradsförskjutning från källraden i uttrycket har alla N-adresser brytpunkter.

Filtrering baserat på symbolindexet

Varje symbol bör ha ett unikt symbolindex. Detaljerad information om symbolernas struktur finns i SYMBOL_INFO struktur.

Felsökaren använder symbolindexet för att se till att dubblettmatchningar filtreras i händelse av flera adresser med noll källradsförskjutning.

Exempel på mallar och överlagrade funktioner

Mallfunktioner

Om du anger en brytpunkt på källraden för definitionen av en mallfunktion resulterar det i en brytpunkt för varje implementering av mallfunktionen. Med följande mallfunktion på rad 19 i BikeCatalog.cpp:

template <class T>
void RegisterBike(T id)
{
    std::cout << "Registered bike " << id << std::endl;
}

Och dess användning:

catalog.RegisterBike("gravel bike");
catalog.RegisterBike(1234);

Om du anropar kommandot bp `BikeCatalog.cpp:19` anges två brytpunkter som matchar implementeringarna av mallfunktionen som används senare i filen. Om användaren i stället vill ange en enda brytpunkt för funktionen måste de antingen ange en brytpunkt på den specifika källraden för mallfunktionens implementering eller ange en brytpunkt för symbolen för mallfunktionen med lämplig typinformation (t.ex. bp BikeCatalog::RegisterBike<int>).

En lista över brytpunkter resulterar i följande utdata:

0:000> bl
     2 e Disable Clear  <hierarchical breakpoint>     0001 (0001)  0:**** {BikeCatalog!BikeCatalog::RegisterBike&lt;int&gt;}
         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 *>

Överlagrade funktioner

Om du anger en brytpunkt på källraden för definitionen av en överlagrad funktion resulterar det bara i en brytpunkt för den definitionen av den överbelastade funktionen. Återanvända kodfragmentet ovanifrån och den första raden börjar på rad 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;
    }
}; 

Om du anropar kommandot bp `BikeCatalog.cpp:9` anges en enda brytpunkt på raden för implementeringen void av GetNumberOfBikes. En lista över brytpunkter resulterar i följande utdata:

0:000> bl
     0 e Disable Clear  00007ff7`6b691ec0  [C:\BikeCatalog\BikeCatalog.cpp @ 9]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes

inlinjerade funktioner

Om du anger en brytpunkt på källraden för anropsplatsen för en inline-funktion kommer det att bara finnas en brytpunkt på den specifika anropsplatsen, även om det finns en annan anropsplats i samma funktion.

Flera hierarkiska brytpunkter

Hierarkiska brytpunkter äger varje brytpunkt i sin uppsättning om inte:

En brytpunkt i sin uppsättning tas bort

  • Den hierarkiska brytpunkten rensas bort.
  • En annan hierarkisk brytpunkt skapas som innehåller en brytpunkt i den här hierarkiska brytpunktens uppsättning.

Ett annat sätt att tänka på detta är att brytpunkter endast kan ha en enda hierarkisk brytpunktsägare och att det senaste brytpunktskommandot avgör vilket tillstånd brytpunktslistan ska ha.

Dessutom kan en hierarkisk brytpunkt inte äga en annan hierarkisk brytpunkt.

Underordna befintliga brytpunkter

Om en brytpunkt A finns på egen hand och ett tvetydigt brytpunktsuttryck matchas för att skapa brytpunkterna A, B, kommer A att ingå i den nya brytpunktsuppsättningen med B.

Undersummera hierarkiska brytpunktsuppsättningskorsningar

Om en hierarkisk brytpunkt A äger brytpunkterna B, C och sedan ett tvetydigt brytpunktsuttryck löses upp för att definiera brytpunkter:

  • B, C, D: Brytpunkter B, C ansluter den nya hierarkiska brytpunktsgruppen med brytpunkt D och hierarkisk brytpunkt A rensas.

  • C, D eller B, D: En av brytpunkterna ansluter den nya hierarkiska brytpunktsgruppen med brytpunkt D, och hierarkisk brytpunkt A fortsätter att finnas med den återstående brytpunkten som inte gick med i den nya gruppen.

Se även

Använda brytpunkter

Brytpunktssyntax

bp, bu, bm (Sätt brytpunkt)

Olösta brytpunkter (bu Brytpunkter)