Bersiap untuk Men-debug Aplikasi Layanan
Topik ini mencantumkan semua langkah persiapan yang mungkin diperlukan sebelum men-debug aplikasi layanan. Langkah mana yang diperlukan dalam skenario Anda bergantung pada opsi lampirkan mana yang telah Anda pilih dan konfigurasi debugging mana yang telah Anda pilih. Untuk daftar pilihan ini, lihat Memilih Metode Terbaik.
Setiap langkah persiapan yang dijelaskan dalam topik ini menentukan kondisi di mana diperlukan. Langkah-langkah ini dapat dilakukan dalam urutan apa pun.
Mengaktifkan Debugging Kode Inisialisasi
Jika Anda berencana untuk men-debug aplikasi layanan dari awal eksekusinya, termasuk kode inisialisasinya, langkah persiapan ini diperlukan.
Temukan atau buat kunci registri berikut, di mana ProgramName adalah nama file yang dapat dieksekusi aplikasi layanan:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName
ProgramName harus menyertakan ekstensi nama file, tetapi bukan jalurnya. Misalnya, ProgramName mungkin Myservice.exe atau Thisservice.dll.
Di bawah kunci registri ini, buat nilai data string berjudul Debugger. Nilai string ini harus diatur ke jalur lengkap dan nama file debugger untuk dilampirkan ke aplikasi layanan.
Jika Anda berencana untuk men-debug secara lokal, gunakan string seperti berikut ini:
c:\Debuggers\windbg.exe
Jangan pilih opsi ini jika Anda menjalankan Windows Vista atau versi Windows yang lebih baru.
Jika Anda berencana menggunakan penelusuran kesalahan jarak jauh, tentukan NTSD dengan opsi -noio. Hal ini menyebabkan NTSD berjalan tanpa konsol sendiri, hanya dapat diakses melalui koneksi jarak jauh. Contohnya:
c:\Debuggers\ntsd.exe -server ServerTransport -noio -y SymbolPath
Jika sesi penelusuran kesalahan Anda dimulai sebelum Windows dimuat sepenuhnya, Anda mungkin tidak dapat mengakses simbol dari berbagi jarak jauh; dalam kasus seperti itu, Anda harus menggunakan simbol lokal. ServerTransport harus menentukan protokol transportasi yang diterapkan oleh kernel Windows tanpa berinteraksi dengan layanan mode pengguna, seperti TCP atau NPIPE. Untuk sintaks ServerTransport, lihat Mengaktifkan Server Debugging.
Jika Anda berencana untuk mengontrol debugger mode pengguna dari debugger mode kernel, tentukan NTSD dengan opsi -d. Contohnya:
c:\Debuggers\ntsd.exe -d -y SymbolPath
Jika Anda berencana untuk menggunakan metode ini dan simbol mode pengguna Anda akan diakses dari server simbol, Anda harus menggabungkan metode ini dengan penelusuran kesalahan jarak jauh. Dalam hal ini, tentukan NTSD dengan opsi -ddefer. Pilih protokol transportasi yang diterapkan oleh kernel Windows tanpa berinteraksi dengan layanan mode pengguna, seperti TCP atau NPIPE. Contohnya:
c:\Debuggers\ntsd.exe -server ServerTransport -ddefer -y SymbolPath
Untuk detailnya, lihat Mengontrol User-Mode Debugger dari Debugger Kernel.
Setelah pengeditan registri ini selesai, debugger diluncurkan setiap kali layanan dengan nama ini dimulai atau dimulai ulang.
Mengaktifkan Aplikasi Layanan untuk Masuk ke Debugger
Jika Anda ingin aplikasi layanan masuk ke debugger saat mengalami crash atau mengalami pengecualian, langkah persiapan ini diperlukan. Langkah ini juga diperlukan jika Anda ingin aplikasi layanan masuk ke debugger dengan memanggil fungsi DebugBreak .
Catatan Jika Anda telah mengaktifkan penelusuran kesalahan kode inisialisasi (langkah yang dijelaskan dalam sub bagian "Mengaktifkan Debugging Kode Inisialisasi"), Anda harus melewati langkah ini. Ketika penelusuran kesalahan kode inisialisasi diaktifkan, debugger melampirkan ke aplikasi layanan saat dimulai, yang menyebabkan semua crash, pengecualian, dan panggilan ke DebugBreak dirutekan ke debugger tanpa persiapan tambahan yang diperlukan.
Langkah persiapan ini melibatkan pendaftaran debugger yang dipilih sebagai debugger postmortem. Ini dilakukan dengan menggunakan opsi -iae atau -iaec pada baris perintah debugger. Kami merekomendasikan perintah berikut, tetapi jika Anda ingin memvariasikannya, lihat detail sintaks dalam Mengaktifkan Debugging Postmortem.
Jika Anda berencana untuk men-debug secara lokal, gunakan perintah seperti berikut ini:
windbg -iae
Jangan pilih opsi ini jika Anda menjalankan Windows Vista atau versi Windows yang lebih baru.
Jika Anda berencana menggunakan penelusuran kesalahan jarak jauh, tentukan NTSD dengan opsi -noio. Hal ini menyebabkan NTSD berjalan tanpa konsol sendiri, hanya dapat diakses melalui koneksi jarak jauh. Untuk menginstal debugger postmortem yang menyertakan parameter -server, Anda harus mengedit registri secara manual; untuk detailnya, lihat Mengaktifkan Debugging Postmortem. Misalnya, nilai Debugger dari kunci AeDebug bisa menjadi sebagai berikut:
ntsd -server npipe:pipe=myproc%x -noio -p %ld -e %ld -g -y SymbolPath
Dalam spesifikasi pipa, token %x diganti dengan ID proses proses yang meluncurkan debugger. Ini menjamin bahwa jika lebih dari satu proses meluncurkan debugger postmortem, masing-masing memiliki nama pipa yang unik. Jika sesi penelusuran kesalahan Anda dimulai sebelum Windows dimuat sepenuhnya, Anda mungkin tidak dapat mengakses simbol dari berbagi jarak jauh; dalam kasus seperti itu, Anda harus menggunakan simbol lokal. ServerTransport harus menentukan protokol transportasi yang diterapkan oleh kernel Windows tanpa berinteraksi dengan layanan mode pengguna, seperti TCP atau NPIPE. Untuk sintaks ServerTransport, lihat Mengaktifkan Server Debugging.
Jika Anda berencana untuk mengontrol debugger mode pengguna dari debugger mode kernel, tentukan NTSD dengan opsi -d. Contohnya:
ntsd -iaec -d -y SymbolPath
Jika Anda memilih metode ini dan berniat untuk mengakses simbol mode pengguna dari server simbol, Anda harus menggabungkan metode ini dengan penelusuran kesalahan jarak jauh. Dalam hal ini, tentukan NTSD dengan opsi -ddefer. Pilih protokol transportasi yang diterapkan oleh kernel Windows tanpa berinteraksi dengan layanan mode pengguna, seperti TCP atau NPIPE. Untuk menginstal debugger postmortem yang menyertakan parameter -server, Anda harus mengedit registri secara manual; untuk detailnya, lihat Mengaktifkan Debugging Postmortem. Misalnya, nilai Debugger dari kunci AeDebug bisa menjadi sebagai berikut:
ntsd -server npipe:pipe=myproc%x -ddefer -p %ld -e %ld -g -y SymbolPath
Untuk detailnya, lihat Mengontrol User-Mode Debugger dari Debugger Kernel.
Ketika Anda mengeluarkan salah satu perintah ini, debugger postmortem terdaftar. Debugger ini akan diluncurkan setiap kali ada program mode pengguna, termasuk aplikasi layanan, mengalami pengecualian atau menjalankan fungsi DebugBreak .
Menyesuaikan Batas Waktu Aplikasi Layanan
Jika Anda berencana untuk meluncurkan debugger secara otomatis (baik ketika layanan dimulai atau ketika menemukan pengecualian), langkah persiapan ini diperlukan.
Temukan kunci registri berikut:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Di bawah kunci ini, temukan atau buat nilai data DWORD yang disebut ServicesPipeTimeout. Atur entri ini ke jumlah waktu dalam milidetik yang Anda inginkan agar layanan menunggu sebelum waktu habis. Misalnya, nilai 60.000 adalah satu menit, sedangkan nilai 86.400.000 adalah 24 jam. Ketika nilai registri ini tidak diatur, batas waktu default adalah sekitar tiga puluh detik.
Signifikansi dari nilai ini adalah bahwa jam mulai berjalan ketika setiap layanan diluncurkan, dan ketika nilai batas waktu tercapai, debugger apa pun yang melekat pada layanan dihentikan. Oleh karena itu, nilai yang Anda pilih harus lebih panjang dari jumlah total waktu yang berlalu antara peluncuran layanan dan penyelesaian sesi penelusuran kesalahan Anda.
Pengaturan ini berlaku untuk setiap layanan yang dimulai atau dimulai ulang setelah pengeditan registri selesai. Jika beberapa layanan macet atau macet dan pengaturan ini masih berlaku, masalahnya tidak terdeteksi oleh Windows. Oleh karena itu, Anda harus menggunakan pengaturan ini hanya saat Anda melakukan debugging, dan mengembalikan kunci registri ke nilai aslinya setelah penelusuran kesalahan Anda selesai.
Mengisolasi Layanan
Terkadang, beberapa layanan digabungkan dalam satu proses Host Layanan (Svchost). Jika Anda ingin men-debug layanan seperti itu, Anda harus terlebih dahulu mengisolasinya ke dalam proses Svchost terpisah.
Ada tiga metode di mana Anda dapat mengisolasi layanan. Microsoft merekomendasikan Memindahkan Layanan ke metode Grupnya Sendiri, sebagai berikut. Metode alternatif (Mengubah Jenis Layanan dan Menduplikasi Biner SvcHost) dapat digunakan secara sementara untuk penelusuran kesalahan, tetapi karena mengubah cara layanan berjalan, mereka tidak dapat diandalkan seperti metode pertama.
Metode yang Disukai: Memindahkan Layanan ke Grupnya Sendiri
Terbitkan perintah alat Konfigurasi Layanan (Sc.exe) berikut, di mana ServiceName adalah nama layanan:
sc qc ServiceName
Ini menampilkan nilai konfigurasi saat ini untuk layanan. Nilai yang menarik adalah BINARY_PATH_NAME, yang menentukan baris perintah yang digunakan untuk meluncurkan program kontrol layanan. Dalam skenario ini, karena layanan Anda belum terisolasi, baris perintah ini menyertakan jalur direktori, Svchost.exe, dan beberapa parameter SvcHost, termasuk sakelar -k, diikuti dengan nama grup. Misalnya, mungkin terlihat seperti ini:
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
Ingat jalur ini dan nama grup; mereka digunakan dalam langkah 5 dan 6.
Temukan kunci registri berikut:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost
Buat nilai REG_MULTI_SZ baru dengan nama unik (misalnya, TempGrp).
Atur nilai baru ini sama dengan nama layanan yang ingin Anda isolasi. Jangan sertakan jalur direktori atau ekstensi nama file apa pun. Misalnya, Anda dapat mengatur nilai baru TempGrp yang sama dengan MyService.
Di bawah kunci registri yang sama, buat kunci baru dengan nama yang sama dengan yang Anda gunakan di langkah 2. Contohnya:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
Sekarang kunci SvcHost berisi nilai dengan nama baru dan juga memiliki kunci subordinat dengan nama yang sama ini.
Cari subordinat kunci lain ke kunci SvcHost yang memiliki nama yang sama dengan grup yang Anda temukan di langkah 1. Jika kunci seperti itu ada, periksa semua nilai di dalamnya, dan buat duplikatnya di kunci baru yang Anda buat di langkah 4.
Misalnya, kunci lama mungkin diberi nama ini:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\LocalServiceNoNetwork
dan mungkin berisi nilai seperti CoInitializeSecurityParam, AuthenticationCapabilities, dan nilai lainnya. Anda akan membuka kunci yang baru dibuat:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
dan buat nilai di dalamnya yang identik dalam nama, jenis, dan data dengan nilai di kunci lama.
Jika kunci lama tidak ada, Anda tidak perlu membuat kunci baru.
Gunakan perintah alat Konfigurasi Layanan berikut untuk merevisi jalur yang ditemukan di langkah 1:
sc config ServiceName binPath= "RevisedPath"
Dalam perintah ini, ServiceName adalah nama layanan, dan RevisedPath adalah nilai baru yang Anda berikan untuk BINARY_PATH_NAME. Untuk RevisedPath, gunakan jalur yang sama persis dengan yang ditampilkan di langkah 1, termasuk semua opsi yang ditampilkan pada baris tersebut, hanya membuat satu perubahan: ganti parameter setelah sakelar -k dengan nama nilai registri baru yang Anda buat di langkah 2. Sertakan RevisedPath dalam tanda kutip. Ruang setelah tanda sama dengan diperlukan.
Misalnya, perintah Anda mungkin terlihat seperti ini:
sc config MyService binPath= "%SystemRoot%\System32\svchost.exe -k TempGrp"
Anda mungkin ingin menggunakan perintah sc qc lagi untuk meninjau perubahan yang telah Anda buat.
Pengaturan ini akan berlaku saat layanan dimulai lagi. Untuk menghapus efek layanan lama, kami sarankan Anda memulai ulang Windows daripada hanya memulai ulang layanan.
Setelah Anda menyelesaikan penelusuran kesalahan, jika Anda ingin mengembalikan layanan ini ke host layanan bersama, gunakan perintah konfigurasi sc lagi untuk mengembalikan jalur biner ke nilai aslinya, dan hapus kunci dan nilai registri baru yang Anda buat..
Metode Alternatif: Mengubah Jenis Layanan
Terbitkan perintah alat Konfigurasi Layanan (Sc.exe) berikut, di mana ServiceName adalah nama layanan:
sc config ServiceName type= own
Ruang setelah tanda sama dengan diperlukan.
Mulai ulang layanan, dengan menggunakan perintah berikut:
net stop ServiceName net start ServiceName
Alternatif ini bukan metode yang direkomendasikan karena dapat mengubah perilaku layanan. Jika Anda menggunakan metode ini, gunakan perintah berikut untuk kembali ke perilaku normal setelah Anda menyelesaikan penelusuran kesalahan:
sc config ServiceName type= share
Metode Alternatif: Menduplikasi Biner SvcHost
File Svchost.exe yang dapat dieksekusi terletak di direktori sistem32 Windows. Buat salinan file ini, beri nama svhost2.exe, dan letakkan di direktori system32 juga.
Terbitkan perintah alat Konfigurasi Layanan (Sc.exe) berikut, di mana ServiceName adalah nama layanan:
sc qc ServiceName
Perintah ini menampilkan nilai konfigurasi saat ini untuk layanan. Nilai yang menarik adalah BINARY_PATH_NAME, yang menentukan baris perintah yang digunakan untuk meluncurkan program kontrol layanan. Dalam skenario ini, karena layanan Anda belum terisolasi, baris perintah ini akan menyertakan jalur direktori, Svchost.exe, dan mungkin beberapa parameter SvcHost. Misalnya, mungkin terlihat seperti ini:
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
Untuk merevisi jalur ini, terbitkan perintah berikut:
sc config ServiceName binPath= "RevisedPath"
Dalam perintah ini, ServiceName adalah nama layanan, dan RevisedPath adalah nilai baru yang Anda berikan untuk BINARY_PATH_NAME. Untuk RevisedPath, gunakan jalur yang sama persis dengan yang ditampilkan di langkah 2, termasuk semua opsi yang ditampilkan pada baris tersebut, hanya membuat satu perubahan: ganti Svchost.exe dengan Svchost2.exe. Sertakan RevisedPath dalam tanda kutip. Ruang setelah tanda sama dengan diperlukan.
Misalnya, perintah Anda mungkin terlihat seperti ini:
sc config MyService binPath= "%SystemRoot%\System32\svchost2.exe -k LocalServiceNoNetwork"
Anda dapat menggunakan perintah sc qc lagi untuk meninjau perubahan yang telah Anda buat.
Mulai ulang layanan dengan menggunakan perintah berikut:
net stop ServiceName net start ServiceName
Alternatif ini bukan metode yang direkomendasikan karena dapat mengubah perilaku layanan. Jika Anda menggunakan metode ini, gunakan perintah konfigurasi sc untuk mengubah jalur kembali ke nilai aslinya setelah Anda menyelesaikan penelusuran kesalahan.