首页 > 代码库 > How do I find what queries were executing in a SQL memory dump?-----stack

How do I find what queries were executing in a SQL memory dump?-----stack

 https://blogs.msdn.microsoft.com/askjay/2010/10/03/how-do-i-find-what-queries-were-executing-in-a-sql-memory-dump/
技术分享

http://blogs.msdn.com/b/askjay/archive/2011/02/18/finding-which-queries-were-executing-from-a-sql-memory-dump-revisited.aspx

—————————————————————————————————-

In this post, we’ll see how to find out which queries were executing from a SQL Server memory dump.   You might have a dump file from a crash of the SQL Service, or you may have taken a diagnostic dump with sqldumper.

What we do in this post assumes you are working with a full or filtered dump of SQL Server.  For more information on dumping SQL Server, read this post:

http://blogs.msdn.com/b/askjay/archive/2010/02/05/how-can-i-create-a-dump-of-sql-server.aspx

Some of the objects contained in the dump that are needed to completely understand this process can only be resolved with private symbols.  What this means is that to fully track down the executing query text, you need to be internal to MS with access to “private” symbols.

However, after finding the query text with the private symbols, we can quickly get to the query text with public symbols and a few specific memory addresses and offsets.

So first, set your public symbol path:

0:000> .sympath srv*c:\symbols\public*http://msdl.microsoft.com/download/symbols 
Symbol search path is:srv*c:\symbols\public*http://msdl.microsoft.com/download/symbols 
0:000> .reload /f sqlservr.exe

Search the stacks:

0:000> ~* k

You are looking for a stack that is executing a query.  It will look like this:

 

Call Site

 
ntdll!ZwWaitForSingleObject+0xa 
KERNELBASE!WaitForSingleObjectEx+0x9c 
sqlservr!SOS_Scheduler::Switch+0xc7 
sqlservr!ThreadScheduler::SwitchNonPreemptive+0xc6 
sqlservr!AutoSwitchPreemptive::~AutoSwitchPreemptive+0x39 
sqlservr!SOS_Task::AutoSwitchPreemptive::~AutoSwitchPreemptive+0x26 
sqlservr!Np::StatusWriteNoComplPort+0xc3 
sqlservr!SNIStatusWriteNoComplPort+0x59 
sqlservr!TDSSNIClient::WriteStatus+0x99 
sqlservr!write_data+0x1bf 
sqlservr!flush_buffer+0xf3 
sqlservr!CKatmaiTds::SendRowImpl+0x19c 
sqlservr!CEs::GeneralEval+0x91f 
sqlservr!CXStmtQuery::ErsqExecuteQuery+0xe3a 
sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0xb6c 
sqlservr!CMsqlExecContext::FExecute+0x593 
sqlservr!CSQLSource::Execute+0x2f9
 
sqlservr!process_request+0x370 
sqlservr!process_commands+0x2b2
 
sqlservr!SOS_Task::Param::Execute+0x11b 
sqlservr!SOS_Scheduler::RunTask+0xca 
sqlservr!SOS_Scheduler::ProcessTasks+0x95 
sqlservr!SchedulerManager::WorkerEntryPoint+0x110 
sqlservr!SystemThread::RunWorker+0x60 
sqlservr!SystemThreadDispatcher::ProcessWorker+0x12c 
sqlservr!SchedulerManager::ThreadEntryPoint+0x12f 
msvcr80!_callthreadstartex+0x17 [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\threadex.c @ 348] 
msvcr80!_threadstartex+0x84 [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\threadex.c @ 326] 
kernel32!BaseThreadInitThunk+0xd 
ntdll!RtlUserThreadStart+0x21

We are interested in the 3rd parameter of the sqlservr!CMsqlExecContext::ExecuteStmts call as seen below:

0e 00000000`0f6eee80 00000000`00e90fe3 : 00000064`00000000

 
00000001`00000000

 
00000000`86909380 
00000000`00000000 
: sqlservr!CMsqlExecContext::ExecuteStmts<1,1>+0xb6c

This is the address of an object, and we need to dump 1 dword at an offset of 0x20 into this object:

0:041>

 dd 86909380+0x020 l1 
00000000`869093a0  869093e0

 

The address at this offset into the object is a property that contains a pointer (another address) to the buffer that contains our query text.  So we get our address from here:

0:041>

 dd 869093e0 l1 
00000000`869093e0  86909470

Now this is the address we need.  So we dump unicode string on this address and we get our query:

0:041>

 du 86909470 
00000000`86909470  "….select * from Sales.SalesOrd" 
00000000`869094b0  "erHeaderroductLevel’);..a"

 

You should be able to follow this approach for most threads executing queries.  The signature of the “ExecuteStmts” function (a method of the CMsqlExecContext object) should have the object address we need as the 3rd parameter provided the stack is the same (the method could be overloaded and take something else as the 3rd parameter in a different situation – but I’d have to check).

-Jay

 

 

 

 

 

 

How do I find what queries were executing in a SQL memory dump?-----stack