Unterbrechen, wenn sich ein Wert mithilfe des Visual Studio-Debuggers ändert

198

Gibt es eine Möglichkeit, eine Variable zu überwachen und Visual Studio nur dann zu unterbrechen, wenn sich dieser Wert ändert?

Es würde es so viel einfacher machen, knifflige staatliche Probleme zu finden.

Kann das gemacht werden?

Für Haltepunktbedingungen muss noch ein Haltepunkt festgelegt werden. Ich möchte lieber eine Überwachung festlegen und Visual Studio die Haltepunkte bei Statusänderungen festlegen lassen.

FlySwat
quelle
Der Haltepunkt hat jedoch keine Auswirkungen, es sei denn, die Bedingung gilt. Sie können Ihren Haltepunkt also an einer beliebigen Stelle (wie dem Setter) platzieren und von dort aus übernehmen. Oder fehlt mir etwas?
Oskar
6
Gut. Es ist wie die vb6-Methode zum Debuggen. Sie interessieren sich nicht für die Haltepunktposition. Fügen Sie einfach einen bedingten Ausdruck hinzu, um das Fenster zu beobachten, und vb6 garantiert, dass es überall dort unterbrochen wird, wo die Bedingung erfüllt ist.
Gulzar Nazim
Entschuldigung, ich habe noch nie einen Weg gesehen, soweit ich weiß, ist der Setter der richtige Weg
Oskar
1
Ich hatte gehofft, bessere Nachrichten zu finden. Das vs2010 zeigt an, dass keine Änderung vorliegt. msdn.microsoft.com/en-us/library/350dyxd0.aspx Nur natives C ++ hat dieses @Scottgu, das Sie besser machen können!
GerryLowry

Antworten:

134

Im Visual Studio 2005-Menü:

Debug -> Neuer Haltepunkt -> Neuer Daten-Haltepunkt

Eingeben:

&myVariable
AShelly
quelle
38
Ist dies für verwalteten Code verfügbar? Ich sehe diese Option für C # -Projekt deaktiviert. Denken Sie daran, irgendwo zu lesen, dass dies eine schwierige Funktion beim Debuggen verwalteter Apps ist, insbesondere wenn der Garbage Collector beteiligt ist.
Gulzar Nazim
27
Es ist leider nur für nicht verwalteten Code verfügbar: msdn.microsoft.com/en-us/library/350dyxd0.aspx
Josh Kodroff
17
Sie können ein Feld auch vorübergehend in eine Eigenschaft konvertieren und einen Haltepunkt auf den Getter oder Setter setzen.
Jon Davis
12
Die Option "Daten-Haltepunkt" unter "Debuggen -> Neuer Haltepunkt" ist deaktiviert. Irgendeine Idee warum? Es bleibt deaktiviert, ob ich tatsächlich debugge oder nicht. Ich benutze Visual Studio 2015.
jbb
2
Ein bisschen spät, aber @jbb für mich ist es nur aktiviert, wenn ich beim Debuggen an einem Haltepunkt angehalten werde.
Allball103
27

Sie können auch festlegen, dass der Code explizit unterbrochen wird:

// Assuming C#
if (condition)
{
    System.Diagnostics.Debugger.Break();
}

Von MSDN:

Debugger.Break: Wenn kein Debugger angehängt ist, werden Benutzer gefragt, ob sie einen Debugger anhängen möchten. Wenn ja, wird der Debugger gestartet. Wenn ein Debugger angehängt ist, wird dem Debugger ein Benutzer-Haltepunkteignal angezeigt, und der Debugger unterbricht die Ausführung des Prozesses so, als ob ein Debugger-Haltepunkt erreicht worden wäre.

Dies ist jedoch nur ein Fallback. Das Festlegen eines bedingten Haltepunkts in Visual Studio, wie in anderen Kommentaren beschrieben, ist die bessere Wahl.

Michael Petrotta
quelle
2
FWIW, mit Bearbeiten und Fortfahren mache ich es lieber so: IME, bedingte Haltepunkte sind langsam
Mark Sowul
Das funktioniert - aber es ist sehr schmerzhaft - ich habe am Ende etwas Ähnliches gemacht - ich habe dies oben auf jede Methode gesetzt, die ich vermutet habe - und wieder unten (in einer finally-Klausel) - auf diese Weise wusste ich genau, welche Die Methode verursachte das Problem - (dh ich wusste, dass die Daten vor dem Eingeben der Methode gut und vor dem Beenden schlecht waren).
BrainSlugs83
26

Wirklich alter Beitrag, aber falls jemand nichts davon weiß ...

In Visual Studio 2015 können Sie einen Haltepunkt auf dem setAccessor einer automatisch implementierten Eigenschaft platzieren. Der Debugger wird unterbrochen, wenn die Eigenschaft aktualisiert wird

public bool IsUpdated
{
    get;
    set;    //set breakpoint on this line
}

Aktualisieren

Alternative; @AbdulRaufMujahid hat in den Kommentaren darauf hingewiesen, dass Sie, wenn sich die automatisch implementierte Eigenschaft in einer einzelnen Zeile befindet, Ihren Cursor auf das get;oder set;und drücken können F9und ein Haltepunkt entsprechend platziert wird. Nett!

public bool IsUpdated { get; set; }
Craig
quelle
5
Selbst wenn sich die automatisch implementierte Eigenschaft in einer Zeile befindet, z. B. der öffentlichen Zeichenfolge UserName {set; bekommen; }. Benutzer kann Getter oder Setter markieren und F9 drücken, um Haltepunkt hinzuzufügen
Abdul Rauf
@AbdulRaufMujahid Super!
Craig
13

Stellen Sie sich vor, Sie haben eine Klasse namens A mit der folgenden Deklaration.

class A  
{  
    public:  
        A();

    private:
        int m_value;
};

Sie möchten, dass das Programm beendet wird, wenn jemand den Wert von "m_value" ändert.

Gehen Sie zur Klassendefinition und setzen Sie einen Haltepunkt in den Konstruktor von A.

A::A()
{
    ... // set breakpoint here
}

Sobald wir das Programm gestoppt haben:

Debug -> Neuer Haltepunkt -> Neuer Daten-Haltepunkt ...

Adresse: & (this-> m_value) Byteanzahl
: 4 (Weil int 4 Bytes hat)

Jetzt können wir das Programm fortsetzen. Der Debugger stoppt, wenn der Wert geändert wird.

Sie können dasselbe mit geerbten Klassen oder zusammengesetzten Klassen tun.

class B
{
   private:
       A m_a;
};

Adresse: & (this-> m_a.m_value)

Wenn Sie die Anzahl der Bytes der Variablen, die Sie untersuchen möchten, nicht kennen, können Sie den Operator sizeof verwenden.

Beispielsweise:

// to know the size of the word processor,  
// if you want to inspect a pointer.
int wordTam = sizeof (void* ); 

Wenn Sie sich den "Aufrufstapel" ansehen, sehen Sie die Funktion, die den Wert der Variablen geändert hat.

Momboco
quelle
1
Also, was genau würdest du tun, wenn das, wonach ich suche, nicht in meinen eigenen Klassen ist? Wie zum Beispiel versuche ich genau herauszufinden, wo ein Steuerelement aktiviert oder deaktiviert wird? Ich kann den Aktivierungswert des Steuerelements während des Debuggens zwar überwachen, aber es gibt keine Möglichkeit, ihn bei Änderungen zu unterbrechen und dann zu überprüfen, wo er gestoppt wurde.
Nyerguds
2
Wenn Sie versuchen, eine externe Bibliothek zu debuggen, muss die Bibliothek im Debug-Modus kompiliert werden. Ich bin nicht mit Komponenten vertraut, aber vielleicht können Sie einen "Rückruf" mit der Eigenschaft verbinden und einen Haltepunkt darin einfügen. Das Formular, das ich beschreibe, benötigt die Speicheradresse. Wenn Sie es nicht wissen können, müssen Sie nach anderen Methoden suchen.
Momboco
9

Ändern Sie die Variable in eine Eigenschaft und fügen Sie der set-Methode einen Haltepunkt hinzu. Beispiel:

private bool m_Var = false;
protected bool var
{
    get { 
        return m_var;
    }

    set { 
        m_var = value;
    }
}
Marcello
quelle
3

Wenn Sie WPF verwenden, gibt es ein großartiges Tool: WPF Inspector .
Es hängt sich an eine WPF-App an und zeigt den vollständigen Steuerelementbaum mit allen Eigenschaften an. Außerdem können Sie (unter anderem) bei jeder Änderung von Eigenschaften eine Unterbrechung vornehmen.

Leider habe ich kein Tool gefunden, mit dem Sie dasselbe mit JEDER Eigenschaft oder Variablen tun können.

Julien N.
quelle
2

Ein Rechtsklick auf den Haltepunkt funktioniert für mich einwandfrei (obwohl ich ihn meistens für bedingte Haltepunkte für bestimmte Variablenwerte verwende. Auch das Brechen von Ausdrücken mit einem Threadnamen funktioniert, was sehr nützlich ist, wenn Sie versuchen, Threading-Probleme zu erkennen).

Oskar
quelle
2

Wie Peter Mortensen schrieb:

Im Visual Studio 2005-Menü:

Debug -> Neuer Haltepunkt -> Neuer Daten-Haltepunkt

Geben Sie ein: & myVariable

Zusätzliche Information:

Offensichtlich muss das System wissen, welche Adresse im Speicher überwacht werden soll. Setzen Sie also einen normalen Haltepunkt auf die Initialisierung von myVariable(oder myClass.m_Variable) - führen Sie das System aus und warten Sie, bis es an diesem Haltepunkt stoppt. - Jetzt ist der Menüeintrag aktiviert und Sie können die Variable durch Eingabe &myVariableoder die Instanz durch Eingabe beobachten &myClass.m_Variable. Jetzt sind die Adressen gut definiert.

Es tut mir leid, wenn ich etwas falsch gemacht habe, indem ich eine bereits gegebene Lösung erklärt habe. Aber ich konnte keinen Kommentar hinzufügen, und es gab einige Kommentare dazu.

R Risack
quelle
1

Sie können einen Speicherüberwachungspunkt in nicht verwaltetem Code verwenden. Ich bin mir nicht sicher, ob diese im verwalteten Code verfügbar sind.

1800 INFORMATIONEN
quelle
1

Sie können die Funktion DebugBreak () wahrscheinlich geschickt einsetzen .

abwischen
quelle
Wie genau? Durch Ausführen eines separaten Threads in einer engen Schleife und Aufrufen von DebugBreak (), wenn eine Änderung festgestellt wurde?
Nalply
@nalpy Sie können beispielsweise die Verwendungsorte verfolgen myVariableund ihre Werte nach der Verwendung in einer Hilfsvariablen speichern previousValueund dann DebugBreak () aufrufen, wenn myVariable!=previousValue; dann würden Sie wissen, zwischen welchen Codeblöcken myVariablesich geändert hat. Aber ich stimme zu, dass AShellys Lösung die beste ist.
Wischen
1

Sie können optional den Operator = für die Variable überladen und den Haltepunkt innerhalb der überladenen Funktion unter bestimmten Bedingungen setzen.

PRIME
quelle
1

Update im Jahr 2019:

Dies wird jetzt offiziell in Visual Studio 2019 Preview 2 für .Net Core 3.0 oder höher unterstützt. Natürlich müssen Sie möglicherweise einige Überlegungen zu potenziellen Risiken bei der Verwendung einer Vorschau-Version von IDE anstellen. Ich kann mir vorstellen, dass dies in naher Zukunft im offiziellen Visual Studio enthalten sein wird.

https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/

Glücklicherweise sind Daten-Haltepunkte nicht mehr exklusiv für C ++, da sie jetzt für .NET Core (3.0 oder höher) in Visual Studio 2019 Preview 2 verfügbar sind!

Matt
quelle