Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 3개 있습니다.)
(시리즈 글이 11개 있습니다.)
.NET Framework: 475. ETW(Event Tracing for Windows)를 C#에서 사용하는 방법
; https://www.sysnet.pe.kr/2/0/1804

.NET Framework: 483. 코드로 살펴 보는 ETW의 활성화 시점
; https://www.sysnet.pe.kr/2/0/1815

.NET Framework: 915. ETW(Event Tracing for Windows)를 이용한 닷넷 프로그램의 내부 이벤트 활용
; https://www.sysnet.pe.kr/2/0/12244

.NET Framework: 923. C# - ETW(Event Tracing for Windows)를 이용한 Finalizer 실행 감시
; https://www.sysnet.pe.kr/2/0/12255

.NET Framework: 932. C# - ETW 관련 Win32 API 사용 예제 코드 (1)
; https://www.sysnet.pe.kr/2/0/12292

.NET Framework: 933. C# - ETW 관련 Win32 API 사용 예제 코드 (2) NT Kernel Logger
; https://www.sysnet.pe.kr/2/0/12296

.NET Framework: 934. C# - ETW 관련 Win32 API 사용 예제 코드 (3) ETW Consumer 구현
; https://www.sysnet.pe.kr/2/0/12299

.NET Framework: 935. C# - ETW 관련 Win32 API 사용 예제 코드 (4) CLR ETW Consumer
; https://www.sysnet.pe.kr/2/0/12300

.NET Framework: 936. C# - ETW 관련 Win32 API 사용 예제 코드 (5) - Private Logger
; https://www.sysnet.pe.kr/2/0/12302

개발 환경 구성: 504. ETW - 닷넷 프레임워크 기반의 응용 프로그램을 위한 명령행 도구 etrace 소개
; https://www.sysnet.pe.kr/2/0/12303

.NET Framework: 994. C# - (.NET Core 2.2부터 가능한) 프로세스 내부에서 CLR ETW 이벤트 수신
; https://www.sysnet.pe.kr/2/0/12474




ETW(Event Tracing for Windows)를 이용한 닷넷 프로그램의 내부 이벤트 활용

ETW(코드네임 Crimson)로,

ETW(Event Tracing for Windows)를 C#에서 사용하는 방법
; https://www.sysnet.pe.kr/2/0/1804

당연히 CLR에서도 관련 이벤트를 제공하고 있습니다. 이를 구현할 수 있는 간단한 소스 코드를 다음의 글에서 소개하고 있는데,

Grab ETW Session, Providers and Events
; http://labs.criteo.com/2018/07/grab-etw-session-providers-and-events/

가만 보면 예전에 윈도우 시스템 측의 ETW 제공자를 다루던 방식과 크게 다르지 않습니다.

C# - 특정 EXE 프로세스를 종료시킨 EXE를 찾아내는 방법
; https://www.sysnet.pe.kr/2/0/11172

단지, "Grab ETW Session, Providers and Events" 글에서의 예제와 차이점이라면 EnableProvider에 전달한 인자 정도만 다르다고 보면 됩니다.

// register handlers for events on the session source
// more on this later...

// decide which provider to listen to with filters if needed
userSession.EnableProvider(
    ClrTraceEventParser.ProviderGuid,
    TraceEventLevel.Verbose,
    (ulong)(
    ClrTraceEventParser.Keywords.Contention |  // thread contention timing
    ClrTraceEventParser.Keywords.Threading |   // threadpool events
    ClrTraceEventParser.Keywords.Exception |   // get the first chance exceptions
    ClrTraceEventParser.Keywords.GCHeapAndTypeNames | 
    ClrTraceEventParser.Keywords.Type | // for finalizer and exceptions type names
    ClrTraceEventParser.Keywords.GC     // garbage collector details
    )
);

그나저나, CLR ETW 제공자(Microsoft-Windows-DotNETRuntime)가 지원하는 이벤트 종류를 보면 "Exception"이 있는데... 그렇다면 혹시 이것을 이용해 procdump로,

try/catch로 조용히 사라진 예외를 파악하고 싶다면?
; https://www.sysnet.pe.kr/2/0/10965

소개했던 역할을 구현할 수 있지 않을까요? ^^ 실제로 다음과 같이 코딩을 하면,

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            ClrEventSourceMonitor.Run();
        }
    }

    // Install-Package Microsoft.Diagnostics.Tracing.TraceEvent -Version 2.0.56
    class ClrEventSourceMonitor
    {
        static TextWriter Out = Console.Out;

        public static int Run()
        {
            // Today you have to be Admin to turn on ETW events (anyone can write ETW events).   
            if (!(TraceEventSession.IsElevated() ?? false))
            {
                Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
                Debugger.Break();
                return -1;
            }

            var sessionName = "SimpleMontitorSession";
            using (var session = new TraceEventSession(sessionName))
            {
                Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) { session.Dispose(); };

                var firstEventTimeMSec = new Dictionary<int, double>();

                session.Source.Clr.ExceptionStart += delegate (ExceptionTraceData data)
                {
                    Process process = null;

                    try
                    {
                        process = Process.GetProcessById(data.ProcessID);
                        string processName = process.ProcessName;

                        /* 원하지 않는 프로세스는 필터링 
                        if (processName == "devenv")
                        {
                            return;
                        }
                        */
                    } 
                    catch
                    {
                        return;
                    }

                    Console.WriteLine($"({data.ProcessID}:{data.TimeStamp}): {data.EventName} --> {data.ExceptionType} : {data.ExceptionMessage}");
                };

                // ClrTraceEventParser.ProviderGuid == {e13c0d23-ccbc-4e12-931b-d9cc2eee27e4}
                // ClrTraceEventParser.ProviderName == "Microsoft-Windows-DotNETRuntime"

                var restarted = session.EnableProvider(
                    ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,
                    (ulong)(ClrTraceEventParser.Keywords.Exception));

                if (restarted)      // Generally you don't bother with this warning, but for the demo we do. 
                    Out.WriteLine("The session {0} was already active, it has been restarted.", sessionName);

                Out.WriteLine("**** Start listening for events");

                session.Source.Process();
                Out.WriteLine();
                Out.WriteLine("Stopping the collection of events.");
            }
            return 0;
        }
    }
}
/*
C:\Windows\System32>logman query providers | findstr "Microsoft-Windows-DotNETRuntime"
Microsoft-Windows-DotNETRuntime          {E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}
Microsoft-Windows-DotNETRuntimeRundown   {A669021C-C450-4609-A035-5AF59AF4DF18}
*/

닷넷 프로세스 내에서 발생하는 (try/catch로 먹어버렸어도) 모든 예외를 출력해 줍니다.

(첨부 파일은 이 글의 예제 코드를 포함합니다.)




첨언하자면, ETW의 특성상 "관리자 권한"으로 실행해야 하는 단점이 있습니다. 또한, 닷넷 4.0 이상의 응용 프로그램에서는 출력이 잘 나오지만,

(12640:2020-06-24 오후 4:29:43): Exception/Start --> System.ApplicationException : TEST

3.5 이하의 응용 프로그램은 예외가 발생했다는 것을 감지만 하고 ExceptionType, ExceptionMessage에 대한 정보는 구할 수 없습니다.

(6516:2020-06-24 오후 4:27:02): Exception/Start -->  :

마지막으로, 실시간으로 이벤트가 전달되지 않고 약간의 시간 차가 생깁니다. 무언가 realtime으로 이벤트를 전달받을 수 있도록 하는 옵션이 있을 것 같은데 딱히 TraceEventSession에서 관련 설정을 찾을 수가 없군요. (혹시 방법을 아시는 분은 덧글 부탁드립니다. ^^)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/24/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2021-07-09 11시00분
GLAD is available (GLAD: GC Latency Analysis and Diagnostics.)
; https://devblogs.microsoft.com/dotnet/556-2/

microsoft/perfview
; https://github.com/microsoft/perfview/
정성태

... 181  182  183  184  185  186  [187]  188  189  190  191  192  193  194  195  ...
NoWriterDateCnt.TitleFile(s)
285정성태6/20/200622617오류 유형: 9. [TFS] Report 관련 서비스를 조회할 때 rsErrorImpersonatingUser 오류 메시지 발생 [1]
284정성태6/19/200620375VS.NET IDE: 40. FxCop - IDE 에서 제공해 주는 SuppressMessage 코드
283정성태1/19/200721218Team Foundation Server: 8. 소스 세이프에서 TFS SourceControl 로 마이그레이션 [2]
279정성태12/27/200626657개발 환경 구성: 3. VS.NET 원격 디버깅 [1]
280정성태6/12/200626083    답변글 개발 환경 구성: 3.1. VS.NET 2003 원격 디버깅 설정
281정성태8/11/200627577    답변글 개발 환경 구성: 3.2. VS.NET 2005 원격 디버깅 설정
315정성태8/11/200628196        답변글 개발 환경 구성: 3.3. VS.NET 2005 원격 디버깅 설정 - ASP.NET F5 디버깅
278정성태6/11/200624737오류 유형: 8. [Outlook] 0x8004011D 에러 - "Exchange over the Internet" 환경
276정성태6/7/200618225Team Foundation Server: 7. 외부 빌드 머신 구성
287정성태6/24/200615841    답변글 Team Foundation Server: 7.1. 외부 빌드 머신 구성 - 다른 블로그 자료
275정성태6/7/200623777디버깅 기술: 4. VC++ 8.0 원격 디버깅 구성 - Side-by-Side DLL 문제.
269정성태6/6/200620985Team Foundation Server: 6. HTTPS를 통한 Team Server 접근 [1]
270정성태6/5/200617924    답변글 Team Foundation Server: 6.1. HTTPS를 통한 Team Server 접근 [1]
273정성태6/6/200620639    답변글 Team Foundation Server: 6.2. 두번째 방법 - HTTPS 를 통한 Team Server 접근 [1]
267정성태6/4/200619950Team Foundation Server: 5. 인터넷으로 Team Server 접근 [2]
266정성태6/8/200616537오류 유형: 7. [설치] mpoai9.dll 관련 오류
265정성태6/1/200624251디버깅 기술: 3. 원격 컴퓨터 디버깅 - VPC 설정
314정성태8/11/200621325    답변글 디버깅 기술: 3.1. Managed 원격 디버깅과 WinDBG 원격 디버깅
264정성태6/1/200630420오류 유형: 6. [VC++ 컴파일] already defined in ntdll.lib(ntdll.dll)
263정성태6/1/200631437디버깅 기술: 2. 커널 구조체 살펴보기 [5]
262정성태6/1/200623748오류 유형: 5. [설치] WinFX Beta2 - 설치시 문제점 해결
261정성태6/1/200620212웹: 3. IIS 6.0 - AppPool을 활용하여 실 서버(운영 서버)에서 디버깅
258정성태6/1/200628129디버깅 기술: 1. 디버깅 방법 - CLR 프로파일러 [1]파일 다운로드1
274정성태6/7/200621035    답변글 디버깅 기술: 1.1. 디버깅 방법 - CLR 프로파일러 ( on Vista )
254정성태6/1/200617536개발 환경 구성: 2. VPC에 Vista 설치하는 방법 [2]
255정성태6/1/200617184    답변글 개발 환경 구성: 2.1. msconfig 설정과 Windows Activation
... 181  182  183  184  185  186  [187]  188  189  190  191  192  193  194  195  ...