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.