Istirahat ketika nilai berubah menggunakan Visual Studio debugger

198

Apakah ada cara untuk menempatkan arloji pada variabel dan hanya memiliki Visual Studio istirahat ketika nilai itu berubah?

Itu akan membuatnya jauh lebih mudah untuk menemukan masalah negara yang rumit.

Bisakah ini dilakukan?

Kondisi breakpoint masih memerlukan set breakpoint, dan saya lebih suka mengatur arloji dan membiarkan Visual Studio mengatur breakpoint pada perubahan keadaan.

FlySwat
sumber
tetapi breakpoint tidak memengaruhi apa pun kecuali kondisinya berlaku, sehingga Anda dapat meletakkan breakpoint Anda di mana saja (seperti Setter) dan mengambilnya dari sana. Atau apakah saya melewatkan sesuatu?
Oskar
6
baik. itu seperti cara debugging vb6. Anda tidak peduli tentang lokasi breakpoint. cukup tambahkan ekspresi kondisional ke jendela tonton dan vb6 akan menjamin itu akan rusak di mana pun kondisi terpenuhi ..
Gulzar Nazim
maaf, tidak pernah melihat jalan, sejauh yang saya tahu setter adalah cara untuk pergi
Oskar
1
saya berharap menemukan berita yang lebih baik; vs2010 menunjukkan tidak ada perubahan msdn.microsoft.com/en-us/library/350dyxd0.aspx hanya asli c ++ yang memiliki @Scottgu ini yang dapat Anda lakukan lebih baik!
gerryLowry

Jawaban:

134

Dalam menu Visual Studio 2005:

Debug -> Breakpoint Baru -> Breakpoint Data Baru

Memasukkan:

&myVariable
ASHelly
sumber
38
apakah ini tersedia untuk kode yang dikelola? Saya melihat opsi ini dinonaktifkan untuk proyek C #. Ingat membaca di suatu tempat ini adalah fitur yang sulit untuk diterapkan dalam debugging aplikasi yang dikelola terutama dengan pengumpul sampah yang terlibat.
Gulzar Nazim
27
Ini hanya tersedia untuk kode yang tidak dikelola, sayangnya: msdn.microsoft.com/en-us/library/350dyxd0.aspx
Josh Kodroff
17
Anda juga dapat sementara mengonversi bidang ke properti dan meletakkan breakpoint pada pengambil atau penyetel.
Jon Davis
12
Opsi "Data Breakpoint" di bawah "Debug -> New Breakpoint" dinonaktifkan .. tahu mengapa? Tetap dinonaktifkan atau tidak saya benar-benar men-debug atau tidak. Saya menggunakan Visual Studio 2015.
jbb
2
Sedikit terlambat tapi @ jbb bagi saya itu hanya diaktifkan ketika saya berhenti pada titik istirahat saat debugging.
Allball103
27

Anda juga dapat memilih untuk memecah secara eksplisit dalam kode:

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

Dari MSDN:

Debugger.Break: Jika tidak ada debugger terpasang, pengguna ditanya apakah mereka ingin melampirkan debugger. Jika ya, debugger akan dimulai. Jika debugger dilampirkan, debugger ditandai dengan peristiwa breakpoint pengguna, dan debugger menunda eksekusi proses seperti jika breakpoint debugger telah dipukul.

Tapi ini hanya mundur. Mengatur breakpoint bersyarat di Visual Studio, seperti yang dijelaskan dalam komentar lain, adalah pilihan yang lebih baik.

Michael Petrotta
sumber
2
FWIW, dengan edit dan lanjutkan, saya lebih suka melakukannya dengan cara ini: IME, breakpoint bersyarat sloooow
Mark Sowul
Ini bekerja - tapi ini sangat menyakitkan - Saya akhirnya melakukan hal yang serupa - Saya meletakkan ini di atas setiap metode yang saya curigai - dan lagi di bagian bawah (dalam klausa akhirnya) - dengan begitu saya tahu persis mana metode menyebabkan masalah - (yaitu saya tahu data itu baik sebelum memasukkan metode, dan kemudian buruk sebelum keluar).
BrainSlugs83
26

Posting yang sangat lama tetapi jika seseorang tidak mengetahui ...

Di Visual Studio 2015 , Anda dapat menempatkan breakpoint pada setaccessor dari Properti yang Diimplementasikan Otomatis dan debugger akan rusak ketika properti diperbarui

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

Memperbarui

Kalau tidak; @AbdulRaufMujahid telah menunjukkan dalam komentar bahwa jika properti yang diimplementasikan otomatis berada pada satu baris, Anda dapat memposisikan kursor Anda di get;atau set;dan menekan F9dan breakpoint akan ditempatkan sesuai. Bagus!

public bool IsUpdated { get; set; }
Craig
sumber
5
Bahkan jika properti yang diimplementasikan otomatis dalam satu baris misalnya string publik UserName {set; Dapatkan; }. Pengguna dapat menyorot pengambil atau penyetel dan dapat menekan F9 untuk menambahkan breakpoint
Abdul Rauf
@AbdulRaufMujahid Luar Biasa!
Craig
13

Bayangkan Anda memiliki kelas bernama A dengan deklarasi berikut.

class A  
{  
    public:  
        A();

    private:
        int m_value;
};

Anda ingin program berhenti ketika seseorang mengubah nilai "m_value".

Pergi ke definisi kelas dan letakkan breakpoint di konstruktor A.

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

Setelah kami menghentikan program:

Debug -> Breakpoint Baru -> Breakpoint Data Baru ...

Alamat: & (ini-> m_value)
Byte Count: 4 (Karena int memiliki 4 byte)

Sekarang, kita dapat melanjutkan program. Debugger akan berhenti ketika nilainya diubah.

Anda dapat melakukan hal yang sama dengan kelas bawaan atau kelas gabungan.

class B
{
   private:
       A m_a;
};

Alamat: & (ini-> m_a.m_value)

Jika Anda tidak tahu jumlah byte variabel yang ingin Anda periksa, Anda bisa menggunakan sizeof operator.

Sebagai contoh:

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

Jika Anda melihat "Panggilan tumpukan" Anda dapat melihat fungsi yang mengubah nilai variabel.

momboco
sumber
1
Jadi, apa tepatnya yang akan Anda lakukan jika hal yang saya cari tidak ada di kelas saya sendiri? Seperti, misalnya, saya mencoba mencari tahu di mana kontrol diaktifkan atau dinonaktifkan? Saya dapat menambahkan arloji pada nilai kontrol yang Diaktifkan selama debugging, tentu saja, tetapi tidak ada cara untuk membuatnya rusak saat perubahan dan kemudian lihat di mana ia berhenti.
Nyerguds
2
Jika Anda mencoba men-debug pustaka eksternal, Anda akan memerlukan pustaka yang dikompilasi dalam mode debug. Saya tidak terbiasa dengan komponen, tetapi mungkin Anda dapat menghubungkan "panggilan balik" ke properti dan meletakkan breakpoint di dalamnya. Bentuk yang saya jelaskan memerlukan alamat memori, jika Anda tidak memiliki cara untuk mengetahuinya, ada untuk mencari metode lain.
momboco
9

Ubah variabel menjadi properti dan tambahkan breakpoint dalam metode yang ditetapkan. Contoh:

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

    set { 
        m_var = value;
    }
}
Marcello
sumber
3

Jika Anda menggunakan WPF, ada alat yang luar biasa: WPF Inspector .
Ini melekat pada aplikasi WPF dan menampilkan pohon kontrol penuh dengan semua properti, yang memungkinkan Anda (di antara hal-hal lain) untuk memecah perubahan properti.

Tetapi sayangnya saya tidak menemukan alat yang memungkinkan Anda melakukan hal yang sama dengan properti atau variabel APA SAJA.

Julien N
sumber
3

Saya ingat cara Anda menggambarkannya menggunakan Visual Basic 6.0 . Di Visual Studio, satu-satunya cara yang saya temukan sejauh ini adalah dengan menentukan kondisi breakpoint .

Gulzar Nazim
sumber
2

Klik kanan pada breakpoint berfungsi dengan baik untuk saya (meskipun sebagian besar saya menggunakannya untuk breakpoint bersyarat pada nilai variabel tertentu. Bahkan memecah ekspresi yang melibatkan karya nama thread yang sangat berguna jika Anda mencoba untuk menemukan masalah threading).

Oskar
sumber
2

Seperti yang ditulis Peter Mortensen:

Dalam menu Visual Studio 2005:

Debug -> Breakpoint Baru -> Breakpoint Data Baru

Masukkan: & myVariable

Informasi tambahan:

Jelas, sistem harus tahu alamat mana dalam memori yang harus ditonton. Jadi - atur breakpoint normal ke inisialisasi myVariable(atau myClass.m_Variable) - jalankan sistem dan tunggu sampai berhenti pada breakpoint itu. - Sekarang entri Menu diaktifkan, dan Anda dapat menonton variabel dengan memasukkan &myVariable, atau instance dengan memasukkan &myClass.m_Variable. Sekarang alamatnya sudah didefinisikan dengan baik.

Maaf ketika saya melakukan kesalahan dengan menjelaskan solusi yang sudah diberikan. Tetapi saya tidak bisa menambahkan komentar, dan ada beberapa komentar mengenai hal ini.

R Risack
sumber
1

Anda dapat menggunakan titik pandang memori dalam kode yang tidak dikelola. Tidak yakin apakah ini tersedia dalam kode terkelola.

INFORMASI 1800
sumber
1

Anda mungkin dapat menggunakan fungsi DebugBreak () dengan cerdas .

usap
sumber
Bagaimana sebenarnya? Dengan menjalankan utas terpisah dalam loop ketat dan menjalankan DebugBreak () setiap kali ada perubahan?
nalply
@nalpy Anda bisa, misalnya, melacak tempat-tempat di mana myVariabledigunakan dan menyimpan nilainya setelah digunakan dalam previousValuevariabel bantu , lalu panggil DebugBreak () ketika myVariable!=previousValue; maka Anda akan tahu di antara blok kode mana yang myVariabletelah berubah. Tetapi saya setuju bahwa solusi AShelly adalah yang terbaik.
usap
1

Anda secara opsional dapat membebani operator = untuk variabel dan dapat menempatkan breakpoint di dalam fungsi kelebihan beban pada kondisi tertentu.

UTAMA
sumber
1

Pembaruan pada tahun 2019:

Ini sekarang secara resmi didukung di Visual Studio 2019 Pratinjau 2 untuk .Net Core 3.0 atau lebih tinggi. Tentu saja, Anda mungkin harus memikirkan risiko potensial menggunakan IDE versi Pratinjau. Saya membayangkan dalam waktu dekat ini akan dimasukkan dalam Visual Studio resmi.

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

Untungnya, breakpoint data tidak lagi menjadi C ++ eksklusif karena sekarang tersedia untuk .NET Core (3.0 atau lebih tinggi) di Visual Studio 2019 Pratinjau 2!

Mat
sumber