Simbol Publik dan Privat
Ketika file simbol .pdb atau .dbg berukuran penuh dibangun oleh linker, file tersebut berisi dua koleksi informasi yang berbeda: data simbol privat dan tabel simbol publik. Koleksi ini berbeda dalam daftar item yang dikandungnya dan informasi yang mereka simpan tentang setiap item.
Data simbol privat mencakup item berikut:
Fungsi
Variabel global
Variabel lokal
Informasi tentang struktur, kelas, dan jenis data yang ditentukan pengguna
Nama file sumber dan nomor baris dalam file tersebut yang sesuai dengan setiap instruksi biner
Tabel simbol publik berisi lebih sedikit item:
Fungsi (kecuali untuk fungsi yang dinyatakan statis)
Variabel global yang ditentukan sebagai extern (dan variabel global lainnya terlihat di beberapa file objek)
Sebagai aturan umum, tabel simbol publik berisi persis item yang dapat diakses dari satu file sumber ke file sumber lainnya. Item yang terlihat hanya dalam satu file objek--seperti fungsi statis , variabel yang bersifat global hanya dalam satu file sumber, dan variabel lokal--tidak disertakan dalam tabel simbol publik.
Kedua kumpulan data ini juga berbeda dalam informasi apa yang mereka sertakan untuk setiap item. Informasi berikut biasanya disertakan untuk setiap item yang terkandung dalam data simbol privat :
Nama item
Alamat item dalam memori virtual
Jenis data dari setiap variabel, struktur, dan fungsi
Jenis dan nama parameter untuk setiap fungsi
Cakupan setiap variabel lokal
Simbol yang terkait dengan setiap baris di setiap file sumber
Rekaman kelalaian pointer bingkai (FPO) untuk setiap fungsi yang digunakan untuk mengakses tumpukan
Di sisi lain, tabel simbol publik hanya menyimpan informasi berikut tentang setiap item yang disertakan di dalamnya:
Nama item.
Alamat item di ruang memori virtual modulnya. Untuk fungsi , ini adalah alamat titik masuknya.
Rekaman kelalaian pointer bingkai (FPO) untuk setiap fungsi.
Dapat mencakup awalan/akhiran simbol yang disebut sebagai dekorasi.
Data simbol publik dapat dianggap sebagai subset data simbol privat dengan dua cara: berisi daftar item yang lebih pendek, dan juga berisi lebih sedikit informasi tentang setiap item. Misalnya, data simbol publik tidak menyertakan variabel lokal sama sekali.
Setiap variabel lokal hanya disertakan dalam data simbol privat, dengan alamat, jenis data, dan cakupannya. Fungsi, di sisi lain, disertakan baik dalam data simbol privat dan tabel simbol publik, tetapi sementara data simbol privat mencakup nama fungsi, alamat, catatan FPO, nama dan jenis parameter input, dan jenis output, tabel simbol publik hanya mencakup nama fungsi, alamat, dan catatan FPO.
Ada satu perbedaan lain antara data simbol privat dan tabel simbol publik. Banyak item dalam tabel simbol publik memiliki nama yang dihiasi dengan awalan, akhiran, atau keduanya. Dekorasi ini ditambahkan oleh pengkompilasi C, pengkompilasi C++, dan perakit MASM. Awalan umum mencakup serangkaian garis bawah atau string __imp_ (menunjuk fungsi yang diimpor). Akhiran umum mencakup satu atau beberapa tanda ( @ ) diikuti oleh alamat atau string identifikasi lainnya. Dekorasi ini digunakan oleh linker untuk membedakan simbol, karena ada kemungkinan bahwa nama fungsi atau nama variabel global dapat diulang di berbagai modul. Dekorasi ini adalah pengecualian untuk aturan umum bahwa tabel simbol publik adalah subset dari data simbol privat.
File Simbol Lengkap dan File Simbol Yang Dilucuti
File simbol lengkap berisi data simbol privat dan tabel simbol publik. File semacam ini terkadang disebut sebagai file simbol privat, tetapi nama ini menyesatkan, untuk file tersebut berisi simbol privat dan publik.
File simbol yang dilucuti adalah file yang lebih kecil yang hanya berisi tabel simbol publik - atau, dalam beberapa kasus, hanya subkumpulan tabel simbol publik. File ini terkadang disebut sebagai file simbol publik.
Membuat File Simbol Lengkap dan Dilucuti
Jika Anda membuat biner dengan Visual Studio, Anda dapat membuat file simbol lengkap atau dilucuti. Untuk informasi tentang membangun simbol yang dilucuti, lihat /PDBSTRIPPED (Strip Private Symbols).
Dengan menggunakan alat BinPlace, Anda dapat membuat file simbol yang dilucuti dari file simbol lengkap. Ketika opsi BinPlace yang paling umum digunakan (-a -x -s -n), file simbol yang dilucuti ditempatkan di direktori yang tercantum setelah sakelar -s , dan file simbol lengkap ditempatkan di direktori yang tercantum setelah sakelar -n . Ketika BinPlace menghapus file simbol, versi file yang dilucuti dan lengkap diberikan tanda tangan yang identik dan informasi identifikasi lainnya. Ini memungkinkan Anda menggunakan salah satu versi untuk penelusuran kesalahan. Untuk informasi selengkapnya tentang BinPlace, lihat BinPlace.
Dengan menggunakan alat PDBCopy, Anda dapat membuat file simbol yang dilucuti dari file simbol lengkap dengan menghapus data simbol privat. PDBCopy juga dapat menghapus subset tertentu dari tabel simbol publik. Untuk detailnya, lihat PDBCopy.
Dengan menggunakan alat SymChk, Anda dapat menentukan apakah file simbol berisi simbol privat. Untuk detailnya, lihat SymChk.
Menampilkan Simbol Publik dan Privat di Debugger
Anda dapat menggunakan WinDbg, KD, atau CDB untuk melihat simbol. Ketika salah satu debugger ini memiliki akses ke file simbol lengkap, ia memiliki informasi yang tercantum dalam data simbol privat dan informasi yang tercantum dalam tabel simbol publik. Data simbol publik berisi dekorasi simbol.
Saat mengakses simbol privat, data simbol privat selalu digunakan karena simbol ini tidak disertakan dalam tabel simbol publik. Simbol-simbol ini tidak pernah dihiasi.
Perintah .symopt (Atur Opsi Simbol) dapat digunakan untuk mengontrol opsi simbol yang menentukan bagaimana simbol publik dan privat digunakan oleh debugger. Misalnya perintah ini mengaktifkan informasi penelusuran kesalahan simbol.
.symopt+ 0x80000000
Opsi berikut mengubah cara simbol publik dan privat digunakan dalam debugger.
Saat opsi SYMOPT_UNDNAME aktif, dekorasi tidak disertakan saat nama simbol publik ditampilkan. Selain itu, saat mencari simbol, dekorasi diabaikan. Saat opsi ini nonaktif, dekorasi ditampilkan saat menampilkan simbol publik, dan dekorasi digunakan dalam pencarian. Simbol privat tidak pernah dihiasi dalam keadaan apa pun. Opsi ini aktif secara default di semua debugger.
Saat opsi SYMOPT_PUBLICS_ONLY aktif, data simbol privat diabaikan, dan hanya tabel simbol publik yang digunakan. Opsi ini nonaktif secara default di semua debugger.
Saat opsi SYMOPT_NO_PUBLICS aktif, tabel simbol publik diabaikan, dan pencarian dan informasi simbol menggunakan data simbol privat saja. Opsi ini nonaktif secara default di semua debugger.
Saat opsi SYMOPT_AUTO_PUBLICS aktif (dan SYMOPT_PUBLICS_ONLY dan SYMOPT_NO_PUBLICS nonaktif), pencarian simbol pertama dilakukan dalam data simbol privat. Jika simbol yang diinginkan ditemukan di sana, pencarian berakhir. Jika tidak, tabel simbol publik dicari. Karena tabel simbol publik berisi subset simbol dalam data privat, biasanya ini mengabaikan tabel simbol publik.
Saat opsi SYMOPT_PUBLICS_ONLY, SYMOPT_NO_PUBLICS, dan SYMOPT_AUTO_PUBLICS semuanya nonaktif, baik data simbol privat maupun tabel simbol publik dicari setiap kali simbol diperlukan. Namun, ketika kecocokan ditemukan di kedua tempat, kecocokan dalam data simbol privat digunakan. Oleh karena itu, perilaku dalam instans ini sama seperti ketika SYMOPT_AUTO_PUBLICS aktif, kecuali bahwa menggunakan SYMOPT_AUTO_PUBLICS dapat menyebabkan pencarian simbol terjadi sedikit lebih cepat.
Berikut adalah contoh di mana perintah x (Periksa Simbol) digunakan tiga kali. Pertama kali, opsi simbol default digunakan, sehingga informasi diambil dari data simbol privat. Perhatikan bahwa ini termasuk informasi tentang alamat, ukuran, dan jenis data array typingString. Selanjutnya, perintah .symopt+ 4000 digunakan, menyebabkan debugger mengabaikan data simbol privat. Ketika perintah x kemudian dijalankan lagi, tabel simbol publik digunakan; kali ini tidak ada informasi ukuran dan jenis data untuk typingString. Akhirnya, perintah .symopt- 2 digunakan, yang menyebabkan debugger menyertakan dekorasi. Ketika perintah x dijalankan pada waktu terakhir ini, versi nama fungsi yang didekorasi, _typingString, ditampilkan.
0:000> x /t /d *!*typingstring*
00434420 char [128] TimeTest!typingString = char [128] ""
0:000> .symopt+ 4000
0:000> x /t /d *!*typingstring*
00434420 <NoType> TimeTest!typingString = <no type information>
0:000> .symopt- 2
0:000> x /t /d *!*typingstring*
00434420 <NoType> TimeTest!_typingString = <no type information>
Melihat Simbol Publik dan Privat dengan Alat DBH
Cara lain untuk melihat simbol adalah dengan menggunakan alat DBH . Tampilkan opsi bantuan menggunakan /?
opsi .
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh /?
dbh dbghelp shell
usage: dbh [-n] [-c] [-d] [-?] [-??] [-p] [targetmodule] [command]
[-n] display noisy symbol spew
[-d] use decorated publics
[-p:XXXX] attaches to process ID XXXX
[-s:SSSS] set symbol path to SSSS
[-c] callbacks return false
[targetmodule] load symbols for specified module
[command] execute command and exit
[-?] display these usage instructions
[-??] display detailed usage instructions
Gunakan alat seperti Tlist untuk mencantumkan ID proses dan opsi -p untuk melampirkan ke proses yang ada.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh -p:4308
DBH menggunakan opsi simbol yang sama dengan debugger. Seperti debugger, DBH membiarkan SYMOPT_PUBLICS_ONLY dan SYMOPT_NO_PUBLICS nonaktif secara default, dan mengaktifkan SYMOPT_UNDNAME dan SYMOPT_AUTO_PUBLICS secara default. Default ini dapat ditimpa oleh opsi baris perintah atau oleh perintah DBH.
Berikut adalah contoh di mana addr perintah DBH 414fe0 digunakan tiga kali. Pertama kali, opsi simbol default digunakan, sehingga informasi diambil dari data simbol privat. Perhatikan bahwa ini mencakup informasi tentang alamat, ukuran, dan jenis data fget fungsi. Selanjutnya, perintah symopt +4000 digunakan, yang menyebabkan DBH mengabaikan data simbol privat. Ketika addr 414fe0 kemudian dijalankan lagi, tabel simbol publik digunakan; kali ini tidak ada informasi ukuran dan jenis data untuk fget fungsi. Akhirnya, perintah symopt -2 digunakan, yang menyebabkan DBH menyertakan dekorasi. Ketika addr 414fe0 dijalankan pada waktu terakhir ini, versi nama fungsi yang didekorasi, _fgets, ditampilkan.
pid:4308 mod:TimeTest[400000]: addr 414fe0
fgets
name : fgets
addr : 414fe0
size : 113
flags : 0
type : 7e
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagFunction (5)
index : 7d
pid:4308 mod:TimeTest[400000]: symopt +4000
Symbol Options: 0x10c13
Symbol Options: 0x14c13
pid:4308 mod:TimeTest[400000]: addr 414fe0
fgets
name : fgets
addr : 414fe0
size : 0
flags : 0
type : 0
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 7f
pid:4308 mod:TimeTest[400000]: symopt -2
Symbol Options: 0x14c13
Symbol Options: 0x14c11
pid:4308 mod:TimeTest[400000]: addr 414fe0
_fgets
name : _fgets
addr : 414fe0
size : 0
flags : 0
type : 0
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 7f
Informasi Tambahan
Untuk informasi tambahan tentang simbol, lihat Sintaks Simbol dan Pencocokan Simbol, Opsi Simbol, Singkatan Status Simbol , dan Pemuatan Simbol Yang Ditangguhkan.