아래 링크과 같이 Jonathan Kehayias의 An XEvent a Day 포스팅 자료에서 Extended Events 를 사용하여 call stack 을 확인하는 방법이 포스팅 되어 있습니다만 SQL Server 2012 에서는 call stack 이 정상적으로 나타나지 않습니다.
An XEvent a Day (24 of 31) – What is the package0.callstack Action?
http://sqlblog.com/blogs/jonathan_kehayias/archive/2010/12/24/an-xevent-a-day-24-of-31-what-is-the-callstack-Action.aspx
위 포스팅 예제와 같이 SQL Server 2008 R2에서는 샘플 예제로 sqlservr.pdb 파일만을 사용하여 Call stack 을 확인하였지만 SQL Server 2012 에서는 추가적으로 더 필요한 pdb 파일들이 있습니다. 간단히 아래 예제로 확인해 보실 수 있습니다.
1. SQL Server mini dump 생성
C:\Program Files\Microsoft SQL Server\110\Shared> sqldumper 980 0 0x0120
-- sqlservr.exe PID : 980
-- SQLDmpr001.dmp 파일이 해당 폴더에 생성됩니다.
2. windbg 실행
가. 심볼 설정 : SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
나. SQLDmpr0001.dmp 파일을 windbg 로 불러옵니다. 아래와 같이 심볼 로딩이 완료되면 windbg 를 종료합니다.
................
Automatically loaded SOS Extension
ntdll!NtWaitForSingleObject+0xa:
000007ff`04962c2a c3 ret
0:000>
3. 심볼 복사
c:\symbols 폴더에 있는 sqldk.pdb, sqllang.pdb, sqlmin.pdb, sqlservr.pdb 4개의 파일을 BIN 폴더로 복사합니다.
C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn
4. 오류 발생
RAISERROR(50001, 20, 1, 'This is an Error!') WITH LOG
5. Extended Event 를 사용하여 Call stack 확인
SELECT n.query('.') AS callstack
FROM
(
SELECT CAST(target_data as xml)
FROM sys.dm_xe_sessions AS s
INNER JOIN sys.dm_xe_session_targets AS t
ON s.address = t.event_session_address
WHERE s.name = 'system_health'
AND t.target_name = 'ring_buffer'
) AS src (target_data)
CROSS APPLY target_data.nodes('RingBufferTarget/event/action[@name="callstack"]') as q(n)
[결과]
<type name="callstack" package="package0" />
<value>XeSqlPkg::CollectSqlText<XE_ActionForwarder>+ec [ @ 0+0x0
XeSqlPkg::CollectSqlTextActionInvoke+29 [ @ 0+0x0
XeSqlPkg::CollectTSqlStack<XE_ActionForwarder>+2fa [ @ 0+0x0
XeSqlPkg::CollectTSqlStackActionInvoke+29 [ @ 0+0x0
XeSqlPkg::error_reported::Publish+138 [ @ 0+0x0
ErrorReportedAutoPublish::Publish+2d3 [ @ 0+0x0
CErrorReportingManager::CwchFormatAndPrint+a7e [ @ 0+0x0
CXStmtError::XretExecute+7e1 [ @ 0+0x0
CMsqlExecContext::ExecuteStmts<1,1>+400 [ @ 0+0x0
CMsqlExecContext::FExecute+a33 [ @ 0+0x0
CSQLSource::Execute+866 [ @ 0+0x0
process_request+73c [ @ 0+0x0
process_commands+51c [ @ 0+0x0
SOS_Task::Param::Execute+21e [ @ 0+0x0
SOS_Scheduler::RunTask+a8 [ @ 0+0x0
SOS_Scheduler::ProcessTasks+299 [ @ 0+0x0
SchedulerManager::WorkerEntryPoint+261 [ @ 0+0x0
SystemThread::RunWorker+8f [ @ 0+0x0
SystemThreadDispatcher::ProcessWorker+3c8 [ @ 0+0x0
SchedulerManager::ThreadEntryPoint+236 [ @ 0+0x0
BaseThreadInitThunk+1a [ @ 0+0x0
RtlUserThreadStart+21 [ @ 0+0x0</value>
</action>
작성자 : Lai Go / 작성일자 : 2013.04.27