如何使用WinDBG跟踪调试ASL/ACPI

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用WinDBG跟踪调试ASL/ACPI相关的知识,希望对你有一定的参考价值。

在现代计算机中,硬件和固件(Bios)都必须符合ACPI规范,以便操作系统可以控制所有模块的自动配置和电源管理。 使用WinDbg调试ACPI代码通常需要两台计算机,一台是目标机(Debuggee),另一台作为主机(Debugger)。下面就介绍一下怎么在两台机器上建立调试环境。
1、配置调试Debuggee的连接方式
Windbg支持COM、1394、USB2.0三种不同的连接方式,看到网上有些文章关于使用USB2.0来连接,需要购买特殊的USB调试线,而且价格不菲,本篇文章就不讨论了。笔记本电脑一般都没有COM端口,只好使用1394或是COM转USB,但在这里我只想讨论怎么使用COM端口来连接。
启动到操作系统,使用bootcfg命令或直接使用文本编辑器修改boot.ini文件,指定调试使用的端口及参数。为了使用COM端口来调试,需要在启动参数中加入/debug参数,并指定/debugport和/baudrate子参数来作为启动项。下面这个boot.ini文件的第一个启动项就是配置使用COM端口。/debugport子参数指出使用Debuggee的哪个COM口,/baudrate指出连接的速度(默认是每秒19200位)。
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)/WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Debugging with Cable" /fastdetect /debug /debugport=COM1 /baudrate=57600
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Microsoft Windows XP Professional" /fastdetect
下面的例子使用bootcfg命令设置第一个启动项使用COM1端口、波特率为115200。bootcfg的/debug开关打开,/port开关及/baud参数指出端口和速度,/ID开关指出修改的是第一个启动项。
bootcfg /debug ON /port COM1 /baud 115200 /ID 1
参考技术A 其实并不是只有在生成不了转储文件的情形下才能使用双机调试,在任何情况下都是可以使用的,尤其是调试内核问题时,双机调试不必限于转储文件类型,均可获得一切可以获得的信息,相当于完全内存转储了。而且,双机调试可以调试到系统启动阶段和

如何设断点????-----使用WinDbg调试SQL Server查询

 http://www.cnblogs.com/woodytu/p/4665427.html

http://www.sqlservercentral.com/blogs/aschenbrenner/2014/05/13/debugging-a-sql-server-query-with-windbg/

 

上一篇文章我给你介绍了WinDbg的入门,还有你如何能附加到SQL Server。今天的文章,我们继续往前一步,我会向你展示使用WinDbg调试SQL Server查询需要的步骤。听起来很有意思?我们开始吧!

假设在你面前有个简单的查询,你想在WinDbg里调试那个特定的查询。听起来很简单,但一旦你开始考虑这个问题,就会碰到很多问题:

  • 在我特定执行的查询上,我如何标识出正确的工作者线程?
  • 在sqlservr.exe里,我应该在哪里设置断点?

我们来具体讲解下这2个问题。

标识出正确的工作者线程

当你在SQL Server里执行一个查询,默认情况下你是不知道查询是在哪个线程上运行的。幸运的是SQL Server在DMV sys.dm_os_threads里提供os_thread_id列来告诉我们。OS线程ID就是用来执行指定查询的。不幸的是你需要从sys.dm_exec_requests直到sys.dm_os_threads连接多个表才可以得到需要的信息。我们来看下面的查询: 

复制代码
1 SELECT R.Session_Id, Th.os_thread_id FROM sys.dm_exec_requests R 
2 JOIN sys.dm_exec_sessions S ON R.session_id = S.session_id 
3 JOIN sys.dm_os_tasks T ON R.task_address = T.task_address 
4 JOIN sys.dm_os_workers W ON T.worker_address = W.worker_address 
5 JOIN sys.dm_os_threads Th ON W.thread_address = Th.thread_address 
6 WHERE S.is_user_process = 1
7 GO
复制代码

在WinDbg里用CTRL+BREAK中断sqlservr.exe。为了切换到sys.dm_os_thread提供的系统线程ID,你可以用下列WinDbg命令:

~~[tid]s

占位符tid的值就是实际的系统线程ID——16进制值。因此你需要来自sys.dm_os_thread的os_thread_id列值转为16进制值,用刚才提到的命令。当你的系统线程ID是4910时,你应该用下列WinDbg命令切换到正确的线程:

~~[132E]s

当你的查询运行时,对于你的产寻,sys.dm_os_thread只显示系统线程ID。因此就有下一个问题:对于一个执行的查询,我如何获得“正确的”系统线程ID。我这里用一个小技巧:首先我运行一个简单的WAITFOR DELAY命令(例如1分钟),然后再运行实际的查询。如果你用这个方法,你需要保证在1个批处理里提交2个T-SQL查询。不然的话,SQL OS调度会放置WAITFOR语句和实际的查询在2个不同的线程!我们来看实际的代码:

复制代码
WAITFOR DELAY \'00:01:00\'

SELECT
   soh.*,
   d.*
FROM Sales.SalesOrderHeader soh
INNER JOIN Sales.SalesOrderDetail d ON soh.SalesOrderID = d.SalesOrderID
WHERE soh.SalesOrderID = 71832
AND d.SalesOrderDetailID = 111793
GO
复制代码

 在等待期间,你需要进行下列操作:

  1. sys.dm_os_thread为你等待的查询获得在不同会话里系统线程ID
  2. 转化系统线程ID为16进制值
  3. 用CTRL+BREAK中断sqlservr.exe
  4. 用~~[tid]命令切换到正确的系统线程ID
  5. 在指定线程上设置断点
  6. 继续sqlservr.exe的运行
  7. 等待直到触发断点

你要在用WAITFOR DELAY语句引起的延迟时间内完成所有这些操作。如果超过这个时间,这个方法就不可靠了。因此在刚开始的时候,你可以用WAITFOR DELAY设置长一点的延迟时间,直到用这个方法你已经有经验了。

在sqlservr.exe里设置“好的”断点

现在你已经从sys.dm_os_thread获得了系统线程ID,而且你用WinDbg挂起了sqlservr.exe的执行。下一步你要在sqlservr.exe里设置断点,这样的话你可以在你的查询里调试并单步执行通过。但什么是好的断点呢?这个看情况:)执行计划里的每个运算符都是用独立的C++类实现的,它里面包含不同的函数。其中一个熟知的函数是GetRow,它返回一行到执行里上迭代器。我的方法如下:在执行计划里,尝试在最左的一个迭代器里设置断点。从我的经验里发现,每个SELECT查询开始于sqlmin!CQueryScan::GetRow的函数调用。

刚开始在指定类和函数上设置断点应该非常有用。当然你需要花很长时间(当单步执行通过代码时),指导你碰到SQL Server有意思的部分,像B树管理器,或者闩锁/旋转锁的实现。但初次试验时,建议你在特定函数设置断点就可以了。你要确保断点设置在正确的线程上,因为你只想调试你特定查询,没别的!用bm命令在指定线程和符号名上设置断点:

~tid bm sqlmin!CQueryScan::GetRow

但你还要意识到你不必提供系统线程ID。bm命令期望一个从零开始数字线程号。当你用~~[132E]s切换到正确的系统线程时,你会在WinDbg左下角看到线程号:

 

当WinDbg提示像47的线程号,你可以用下列命令在正确的线程上,在sqlmin!CQueryScan::GetRow函数设置断点:

~47 bm sqlmin!CQueryScan::GetRow

设置断点后,你可以用F5继续sqlservr.exe的运行。几秒后(取决于在WAITFOR语句上设置的延迟)WinDbg应该会在特定的断点中断:

 

现在好戏才开始:你可以用k命令探索当前的调用堆栈,你可以对汇编代码单步执行通过,看看其他函数是如何调用的。梦想有多远,你的选择就有多远(Your choices are endless, and only limited by your imagination.)。

小结

希望这篇文章已经给你以下内容深入的介绍:

sqlservr.exe里对于指定的查询进行调试时,如何成功的设置断点。

请继续关注并玩“坏”WinDbg!

感谢关注!

参考文章:

https://www.sqlpassion.at/archive/2014/05/13/debugging-a-sql-server-query-with-windbg/

注:此文章为WoodyTu学习MS SQL技术,收集整理相关文档撰写,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,有了您的支持才能激发作者更大的写作热情,非常感谢!

以上是关于如何使用WinDBG跟踪调试ASL/ACPI的主要内容,如果未能解决你的问题,请参考以下文章

通过USB架设ASL code的WinDbg

如果使用WINDBG来调试C语言程序.

Windbg 堆栈跟踪问题

常见WinDbg问题及解决方案

WinDbg x64:无法调试故障转储 - 无法加载数据访问 DLL

如何使用 Windbg 从程序开始进行调试?