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 dari titik henti berakhir di 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 disisipkan.
  • Mengatur titik henti dalam fungsi templat dengan beberapa instansiasi di jendela sumber.

Saat diaktifkan, debugger akan menetapkan 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

Menyelesaikan ekspresi titik henti yang ambigu hanya berlaku ketika menjalankan perintah untuk menetapkan satu titik henti di 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 lebih kecocokan yang akan digunakan untuk mengatur titik henti, maka titik henti lain dibuat yang akan mengendalikan titik henti yang diatur. Titik henti penggantian ini, titik henti hierarkis, dapat diaktifkan/dinonaktifkan/dihapus dan dicantumkan sama seperti titik henti normal, dengan kemampuan tambahan 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 titik henti yang sesuai juga akan mengikuti.

.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 template parsial tidak didukung oleh debugger dan tidak ada titik henti yang akan ditetapkan dalam hal ini.

  • Fungsi yang disisipkan: Setiap lokasi disisipkan 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 mengarah ke beberapa lokasi tetapi ekspresi foo+5 dievaluasi, debugger tidak akan mencoba mengarahkan semua lokasi agar titik henti dapat 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 inline: Titik henti diatur untuk setiap lokasi pemanggilan, kecuali jika baris yang ditentukan telah dioptimalkan sebagai bagian dari proses inline.
  • Ditetapkan pada beberapa lokasi: Jika kondisi di atas tidak terpenuhi, maka titik henti akan dibuat 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 menggunakan indeks simbol agar kecocokan duplikat terfilter jika beberapa alamat tanpa perpindahan baris sumber.

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. Berdasarkan fungsi templat di baris 19 pada 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 dikaitkan ke implementasi dari fungsi template 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 menetapkan satu titik henti pada baris yang terkait dengan implementasi void dari 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 yang di-inline

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

Beberapa titik pemisah hierarkis

Titik henti hierarkis akan menguasai setiap titik henti dalam kumpulannya kecuali:

Titik penghentian dalam rangkaiannya dihapus

  • Titik henti hierarkis dibersihkan.
  • Titik henti hierarkis lain dibuat yang menyertakan titik henti dalam kumpulan titik henti hierarkis tersebut.

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.

Menggabungkan 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 perpotongan himpunan titik pemutus hierarkis

Jika titik henti hierarkis A memiliki titik henti B, C, ekspresi titik henti yang ambigu kemudian 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 yang Belum Teratasi (bu Titik Henti)