windbg调试服务程序

    相比通过输出日志来跟踪程序运行状态,我更倾向使用调试器。虽然我早知调试服务很麻烦,总不会比调试驱动还麻烦吧?基于这个想法,我尝试了在win7上使用windbg调试服务并记录于此。

    windows上服务程序可分为两部分:服务安装程序和后台服务程序本身。服务安装程序路数比较固定,几乎不会出错,所以本文仅记录了调试后台服务程序的过程。我在服务管理器中创建了一个显示名为test的服务,ImagePath为:C:\Users\Administrator\Desktop\svr\Debug\srv.exe。

1.设置srv.exe,使其启动时自动启动windbg,这么设置的原因是为了方便调试服务的入口函数ServiceMain。用管理员权限开启windbg目录下的gflags.exe,在"Image File"标签页中填写Image名字(不用写全路径,当exe启动时,加载器会搜索注册表HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image file execution options下的项,如果有同名项,就为其加载Debugee)和调试器的路径。


2.设置test服务的属性,允许服务以交互式启动。


(一般情况下,这样设置就可以在服务管理器中右键启动服务。但是有些机器可能会失败,这可能是注册表路径:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\NoInteractiveServices被置1----禁止服务交互)

3.设置结束后,即可在服务管理器中右键启动服务。启动时,Win7会弹出"Interactive Services Detection"对话框,选"View the message"即可以windbg调试的方式启动服务。


4.刚进入服务时,程序其实停留在main函数的StartServiceCtrlDispatcher函数内,尚未调用服务入口函数ServiceMain。这时需要尽快恢复程序执行让它今早执行完StartServiceCtrlDispatcher函数,否则服务管理器会因为长时间收不到来自服务的消息而终止服务的运行。(参见<深入解析Windows操作系统>4.2 服务启动 一节)。为了能使windbg在ServiceMain处中断,可以在服务入口加 int 3断点。之后,我们就可以慢慢的设置调试符号/下断点等。


5.另外,除了这种调试方式,还有Attach进程的调试方式。这种方式适合在确定ServiceMain没有问题后,调试服务创建的子线程。

<think>好的,我现在需要回答用户关于如何使用WinDbg调试服务程序的问题。首先,我得回想一下WinDbg的基本用法和调试服务程序的步骤。可能用户对WinDbg不太熟悉,所以需要从基础开始讲起,但也不能太冗长,要突出重点。 首先,WinDbg是微软的调试工具,主要用于内核和用户模式的调试服务程序通常以Windows服务的形式运行,作为后台进程,不像普通应用程序那样直接启动,所以调试起来可能比较麻烦。我需要说明如何附加到正在运行的服务进程,或者如何配置服务以启动时调试。 然后,可能的步骤包括:附加到现有进程、配置服务启动参数以启动调试器、设置符号路径、下断点、分析崩溃转储等。还需要考虑服务无法直接启动的情况,可能需要使用sc命令修改服务的启动参数,或者使用调试器启动服务。 需要注意的是,服务程序可能以SYSTEM账户运行,权限问题可能导致调试器无法附加,这时候可能需要以管理员权限运行WinDbg。另外,服务启动时可能需要暂停,以便有时间附加调试器,或者设置延迟启动。 另外,符号文件(PDB)的路径设置很重要,否则调试时看不到有用的信息。需要提醒用户正确配置符号路径,包括微软的公共符号服务器。 可能还需要解释如何设置断点,比如在服务启动时的主要函数设置断点,或者在服务特定的函数上。如果服务崩溃,如何分析dump文件。 还有,用户可能不知道如何让服务在启动时等待调试器附加,这时候可能需要使用“-d”选项或者修改注册表ImagePath,添加调试器路径和服务exe的路径。例如,使用WinDbg作为调试器,在服务启动时自动启动调试器。 另外,调试完成后需要恢复服务的原始配置,避免服务每次启动都启动调试器,导致无法正常使用。 还需要注意,不同的Windows版本可能有细微差异,但大部分步骤是通用的。可能还需要提到使用命令行工具如sc config来修改服务参数,或者使用任务管理器查找服务对应的进程ID,以便附加调试器。 最后,可能还要给出一个示例步骤,让用户更容易理解,比如具体的命令和操作流程。同时提醒常见问题,比如权限不足、符号路径错误、服务无法启动等。</think>使用 WinDbg 调试 Windows 服务程序需要特殊处理,因为服务通常在后台运行且无法直接启动调试器。以下是详细步骤和注意事项: --- ### **一、准备工作** 1. **安装 WinDbg** 从 [Windows SDK](https://developer.microsoft.com/windows/downloads/windows-sdk/) 或 [Windows 驱动程序工具包 (WDK)](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) 中安装最新版 WinDbg。 2. **符号文件配置** 在 WinDbg 中设置符号路径(Symbol Path)以加载调试符号: ```bat .sympath srv*https://msdl.microsoft.com/download/symbols;c:\myservice\pdb ``` - `srv*`:自动下载微软公共符号(如系统 DLL)。 - `c:\myservice\pdb`:指向你的服务程序 PDB 文件路径。 3. **以管理员身份运行 WinDbg** 服务通常以 SYSTEM 账户运行,需提升权限才能调试。 --- ### **二、调试方法** #### **方法 1:附加到已运行的服务进程** 1. **查找服务进程的 PID** - 打开任务管理器 → 详细信息 → 查找服务对应的进程名和 PID。 - 或使用命令提示符: ```bat tasklist /svc ``` 2. **附加进程** - WinDbg → `File` → `Attach to Process` → 选择目标 PID。 - 或命令行启动时附加: ```bat windbg -pn MyService.exe ``` --- #### **方法 2:启动服务时直接调试** 1. **修改服务启动参数** - 使用 `sc config` 命令修改服务的启动命令,使服务启动时触发调试器: ```bat sc config MyService binPath= "\"C:\Debuggers\windbg.exe\" -g -G \"C:\MyService\MyService.exe\"" ``` - **参数说明**: - `-g`:在进程启动时立即中断。 - `-G`:进程终止时保持调试器活动(可选)。 - **注意**:调试完成后需恢复原始路径: ```bat sc config MyService binPath= "C:\MyService\MyService.exe" ``` 2. **启动服务** ```bat sc start MyService ``` - 服务启动时会自动调用 WinDbg,并中断在初始断点处(如 `ntdll!LdrpDoDebuggerBreak`)。 --- #### **方法 3:调试服务崩溃(分析转储文件)** 1. **生成转储文件** - 使用 Procdump 在崩溃时捕获内存转储: ```bat procdump -ma -e -w MyService.exe C:\dumps ``` 2. **分析转储文件** - 在 WinDbg 中打开 `.dmp` 文件: ```bat .open -a C:\dumps\MyService.dmp ``` - 使用命令分析崩溃原因(如 `!analyze -v`)。 --- ### **三、常用调试命令** | 命令 | 说明 | |------------------------|--------------------------------------| | `g` | 继续运行程序 | | `.reload /f` | 强制重新加载符号 | | `bp MyService!Function` | 在指定函数设置断点 | | `!analyze -v` | 分析崩溃原因 | | `lm` | 列出已加载模块 | | `~*kv` | 查看所有线程调用栈 | --- ### **四、注意事项** 1. **服务超时问题** Windows 服务默认 30 秒内需启动完成,若调试时长时间暂停可能导致服务启动失败。可通过注册表调整超时时间: ```bat reg add "HKLM\SYSTEM\CurrentControlSet\Control" /v ServicesPipeTimeout /t REG_DWORD /d 360000 /f ``` 2. **权限问题** - 确保 WinDbg 以管理员权限运行。 - 若服务以 SYSTEM 账户运行,需使用 `psexec -s windbg.exe` 启动调试器。 3. **调试服务初始化代码** 在服务入口函数(如 `main()` 或 `ServiceMain`)设置断点,确保调试器能捕获初始流程。 --- 通过以上方法,你可以有效调试服务程序的启动、运行和崩溃问题。调试完成后,务必恢复服务配置以确保正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值