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<int>}
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
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk