Bagikan melalui


Resolusi titik henti ambigu

Dalam versi 10.0.25310.1001 dan yang lebih baru dari mesin debugger, resolusi titik henti ambigu sekarang didukung.

Titik henti ambigu memungkinkan debugger mengatur titik henti dalam skenario tertentu di mana ekspresi titik henti diselesaikan ke beberapa lokasi. Misalnya, ini dapat terjadi ketika:

  • Beberapa kelebihan beban fungsi.
  • Ada beberapa simbol yang cocok dengan ekspresi titik henti.
  • Nama simbol yang sama digunakan untuk beberapa lokasi.
  • Simbol telah di-inlin.
  • Mengatur titik henti dalam fungsi templat dengan beberapa instansiasi di jendela sumber.

Saat diaktifkan, debugger akan mengatur titik henti pada setiap kecocokan simbol untuk ekspresi titik henti tertentu. Debugger juga akan memfilter kecocokan simbol jika kriteria tertentu terpenuhi.

Untuk informasi umum tentang menggunakan titik henti, lihat Menggunakan Titik Henti.

Mengaktifkan resolusi titik henti ambigu

Secara default, titik henti ambigu dinonaktifkan. Untuk mengaktifkan ini dalam sesi debugger, jalankan perintah ini di konsol WinDbg:

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

Untuk mengonfirmasi bahwa pengaturan titik henti ambigu aktif:

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

Untuk informasi selengkapnya tentang menggunakan perintah dx, lihat dx (Ekspresi Model Objek Debugger Tampilan).

Untuk menonaktifkan fitur, atur nilai di atas menjadi false. Untuk memastikan bahwa pengaturan tetap ada di seluruh sesi, pastikan untuk mengklik File -> Settings -> Debugger Settings lalu centang kotak bertanda Persist engine settings across debugger sessions.

Penggunaan berlaku untuk titik henti tunggal

Mengatasi ekspresi titik henti ambigu hanya berlaku untuk menjalankan perintah titik henti untuk mengatur satu titik henti dalam debugger. Dengan kata lain, mengatur beberapa titik henti dengan bm perintah akan terus berfungsi seperti biasa. Menjalankan perintah dengan fitur ini diaktifkan, akan menghasilkan perilaku titik henti baru untuk titik henti tunggal.

Untuk informasi umum tentang perintah titik henti, lihat bp, bu, bm (Atur Titik Henti).

Titik henti hierarkis

Titik henti hierarkis mewakili hasil menyelesaikan ekspresi titik henti ambigu ke beberapa titik henti. Jika ekspresi menghasilkan dua atau beberapa kecocokan yang akan digunakan untuk mengatur titik henti, maka titik henti lain dibuat yang akan mengontrol set titik henti. Titik henti penimpaan ini, titik henti hierarkis, dapat diaktifkan/dinonaktifkan/dihapus dan dicantumkan sama seperti titik henti normal, dengan fungsionalitas tambahan untuk melakukan operasi yang sama pada titik henti yang dimilikinya.

Misalnya, jika perintah bp foo!bar dijalankan, menghasilkan dua kecocokan terhadap simbol bar, maka titik henti hierarkis akan dibuat yang mengontrol dua kecocokan. Jika hierarki diaktifkan/dinonaktifkan/dihapus, maka juga akan menjadi titik henti yang cocok.

.bpcmds(Tampilkan Perintah Titik Henti) akan mencantumkan perintah titik henti yang dapat dijalankan untuk mengatur setiap titik henti. Titik henti yang dimiliki oleh titik henti hierarkis masih akan mencantumkan perintah bp valid yang akan mengatur titik henti pada alamatnya. Titik henti hierarkis juga akan tercantum dalam output dan akan menampilkan perintah yang dapat digunakan untuk membuat ulang seluruh set titik henti alih-alih hanya satu titik henti.

Simbol ambigu

Mengatur titik henti pada nama simbol akan mengakibatkan perilaku berikut jika simbolnya adalah:

  • Kelebihan beban: Setiap kelebihan beban yang cocok dengan simbol harus memiliki titik henti.

  • Fungsi templat:

    • Jika ekspresi memiliki semua parameter templat yang ditentukan (misalnya bp foo!bar<int>), maka titik henti akan diatur pada implementasi tertentu dari fungsi templat.

    • Jika ekspresi tidak memiliki implementasi jenis yang ditentukan (misalnya bp foo!bar), maka tidak ada titik henti yang akan diatur. Dalam hal ini, bm harus digunakan untuk mengatur titik henti pada fungsi templat.

    • Spesifikasi templat parsial tidak didukung oleh debugger dan tidak ada titik henti yang akan diatur dalam kasus tersebut.

  • Fungsi inlined: Setiap lokasi bergaris memiliki titik henti

Perhatikan bahwa beberapa titik henti tidak akan diatur ketika ekspresi simbol menyertakan operator atau offset yang memerlukan lebih banyak evaluasi oleh debugger. Misalnya, jika simbol foo diselesaikan ke beberapa lokasi tetapi ekspresi foo+5 dievaluasi, debugger tidak akan mencoba menyelesaikan semua lokasi agar titik henti diatur.

Contoh kode titik henti

Mengingat cuplikan kode berikut:

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

Memanggil perintah bu BikeCatalog::GetNumberOfBikes akan mengakibatkan dua titik henti dibuat, satu untuk setiap kelebihan beban. Mencantumkan titik henti akan menghasilkan output berikut:

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

Baris sumber ambigu

Mengatur titik henti pada baris sumber akan mengakibatkan perilaku berikut jika baris sumber adalah:

  • Fungsi yang dioptimalkan kompilator: Jika garis dibagi di beberapa lokasi karena pengoptimalan kompilator, maka titik henti akan diatur pada lokasi terendah dalam fungsi yang sesuai dengan baris yang ditentukan.
  • Fungsi inlined: Titik henti diatur untuk setiap situs panggilan, kecuali baris yang ditentukan telah dioptimalkan sebagai bagian dari inlining.
  • Diselesaikan ke beberapa lokasi: Jika kondisi di atas tidak terpenuhi, maka titik henti akan diatur untuk setiap alamat dengan kondisi berikut:
    • Jika ada sekumpulan alamat N yang cocok dengan baris sumber dalam ekspresi, dan subset M dari alamat N ini tidak memiliki perpindahan baris sumber dari baris sumber dalam ekspresi, maka hanya alamat M yang akan memiliki titik henti.
    • Jika tidak ada alamat dalam kumpulan alamat N yang tidak memiliki perpindahan baris sumber nol dari baris sumber dalam ekspresi, maka semua alamat N akan memiliki titik henti.

Pemfilteran berdasarkan indeks simbol

Setiap simbol harus memiliki indeks simbol yang unik. Untuk informasi terperinci tentang struktur simbol, lihat struktur SYMBOL_INFO.

Debugger akan menggunakan indeks simbol untuk memastikan kecocokan duplikat difilter jika beberapa alamat dengan perpindahan baris sumber nol.

Contoh templat dan fungsi yang kelebihan beban

Fungsi templat

Mengatur titik henti pada baris sumber untuk definisi fungsi templat akan menghasilkan titik henti untuk setiap implementasi fungsi templat. Mengingat fungsi templat berikut pada baris 19 dari BikeCatalog.cpp:

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

Dan penggunaannya:

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

Memanggil perintah bp `BikeCatalog.cpp:19` akan mengatur dua titik henti yang diselesaikan ke implementasi fungsi templat yang digunakan nanti dalam file. Jika sebaliknya pengguna ingin mengatur satu titik henti pada fungsi, mereka harus mengatur titik henti pada baris sumber tertentu dari implementasi fungsi templat atau mengatur titik henti pada simbol fungsi templat dengan informasi jenis yang sesuai (misalnya bp BikeCatalog::RegisterBike<int>).

Mencantumkan titik henti menghasilkan output berikut:

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 *>

Fungsi berlebih

Mengatur titik henti pada baris sumber untuk definisi fungsi yang kelebihan beban hanya akan menghasilkan satu titik henti pada definisi fungsi yang kelebihan beban. Menggunakan kembali cuplikan kode dari atas, dengan baris pertama dimulai pada baris 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;
    }
}; 

Memanggil perintah bp `BikeCatalog.cpp:9` akan mengatur satu titik henti pada baris untuk void implementasi GetNumberOfBikes. Mencantumkan titik henti menghasilkan output berikut:

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

fungsi inlined

Mengatur titik henti pada baris sumber untuk situs panggilan fungsi yang di-inlining hanya akan menghasilkan satu titik henti pada situs panggilan tertentu, bahkan jika ada situs panggilan lain yang ada dalam fungsi yang sama.

Beberapa titik henti hierarkis

Titik henti hierarkis akan memiliki setiap titik henti dalam setnya kecuali:

Titik henti dalam setnya dibersihkan

  • Titik henti hierarkis dibersihkan.
  • Titik henti hierarkis lain dibuat yang menyertakan titik henti dalam set titik henti hierarkis ini.

Cara lain untuk memikirkan hal ini adalah bahwa titik henti mungkin hanya memiliki satu pemilik titik henti hierarkis dan bahwa perintah titik henti terbaru akan menentukan status daftar titik henti.

Selain itu, titik henti hierarkis tidak dapat memiliki titik henti hierarkis lain.

Subjudul titik henti yang sudah ada sebelumnya

Jika titik henti A ada sendiri dan kemudian ekspresi titik henti ambigu diselesaikan untuk membuat titik henti A, B, maka A akan disertakan dalam titik henti baru yang diatur dengan B.

Subsuming titik henti hierarkis mengatur persimpangan

Jika titik henti hierarkis A memiliki titik henti B, C , lalu ekspresi titik henti ambigu diselesaikan untuk membuat titik henti:

  • B, C, D: Breakpoints B, C akan bergabung dengan grup titik henti hierarkis baru dengan titik henti D, dan titik henti hierarkis A akan dihapus.

  • C, D atau B, D: Salah satu titik henti akan bergabung dengan grup titik henti hierarkis baru dengan titik henti D, dan titik henti hierarkis A akan terus ada dengan satu titik henti yang tersisa yang tidak bergabung dengan grup baru.

Lihat juga

Menggunakan Titik Henti

Sintaks Titik Henti

bp, bu, bm (Set Breakpoint)

Titik Henti Tidak Terselesaikan (bu Titik Henti)