ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DebugView] - 사용하기
    .NET/Tools, Library 2018. 9. 14. 10:04

    DebugView 사용하기

    https://docs.microsoft.com/en-us/sysinternals/downloads/debugview

     

    DebugView - Windows Sysinternals

    This program intercepts calls made to DbgPrint by device drivers and OutputDebugString made by Win32 programs.

    docs.microsoft.com

     

    DebugView는 .NET Framework로 Application 개발시 유용한 툴입니다.

    개발시에 System.Diagnostics Namespace 에 있는 Debug, Trace 클래스를 활용하여 디버깅 용도로 사용됩니다.

    C, C++ 에서는 Windows.h 에서 제공하는 OutputDebugString 함수를 사용하면 해당 DebugView에서 볼수있습니다.

     

    Debug

    코드 디버깅에 도움이 되는 메서드 및 속성들을 제공합니다.

    https://msdn.microsoft.com/ko-kr/library/system.diagnostics.debug(v=vs.110).aspx

     

    Trace

    메서드의 집합을 제공 및 코드의 실행을 추적 하는데 도움이 되는 속성입니다. 이 클래스는 상속될 수 없습니다.

    https://msdn.microsoft.com/ko-kr/library/system.diagnostics.trace(v=vs.110).aspx

     

    Program.cs

    using System;
    
    namespace UseDebugView
    {
        class Program
        {
            static void Main(string[] args)
            {
                Toolkit.DebugWriteLine("Debug!");
                Toolkit.TraceWriteLine("Trace!");
    
                Console.WriteLine("Press any key to continue..");
                Console.ReadKey();
            }
        }
    }

    Toolkit.cs

    using System;
    using System.Diagnostics;
    using System.Reflection;
    
    namespace UseDebugView
    {
        internal class Toolkit
        {
            /// <summary>
            /// DebugView Filter 이름
            /// <para>Filter/Hightlight 메뉴 Include 항목에 사용될 값</para>
            /// </summary>
            public static string IncludeFilterName
            {
                get { return _sIncludeFilterName; }
                set
                {
                    if (!String.IsNullOrEmpty(value) && value.Length > 1)
                    {
                        _sIncludeFilterName = value;
                    }
                }
            }
            public static string _sIncludeFilterName;
    
            /// <summary>
            /// <see cref="System.Diagnostics.Debug"/>.WriteLine 메서드 출력 여부
            /// </summary>
            public static bool IsDebugEnabled;
    
            /// <summary>
            /// <see cref="System.Diagnostics.Trace"/>.WriteLine 메서드 출력 여부
            /// </summary>
            public static bool IsTraceEnabled;
    
            /// <summary>
            /// 메시지 출력시 현재시간 출력 여부
            /// </summary>
            public static bool UseNowToString;
            static Toolkit()
            {
    
    #if DEBUG
                _sIncludeFilterName = CreateNamespace();
                IsDebugEnabled = true;
    #else
                _sIncludeFilterName = "ApplicationName";
                IsDebugEnabled = false;
    #endif
                IsTraceEnabled = true;
                UseNowToString = false;
            }
    
            private static string CreateNamespace()
            {
                Assembly assembly = Assembly.GetAssembly(typeof(Toolkit));
                return assembly.GetName().Name;
            }
    
            private static string NowToString(string format = "yyyy/MM/dd HH:mm:ss")
            {
                return DateTime.Now.ToString(format);
            }
    
            public static void DebugWriteLine(string message)
            {
                if (IsDebugEnabled)
                {
                    string className = new StackFrame(1).GetMethod().ReflectedType.Name;
                    string methodName = new StackFrame(1, true).GetMethod().Name;
                    if (UseNowToString)
                    {
                        message = String.Format("[{0}] [{1}.{2}] {3} DEBUG - {4}", 
                            _sIncludeFilterName, className, methodName, NowToString(), message);
                    }
                    else
                    {
                        message = String.Format("[{0}] [{1}.{2}] DEBUG - {3}",
                            _sIncludeFilterName, className, methodName, message);
                    }
    
                    Debug.WriteLine(message);
                }
            }
            public static void TraceWriteLine(string message)
            {
                if (IsTraceEnabled)
                {
                    string className = new StackFrame(1).GetMethod().ReflectedType.Name;
                    string methodName = new StackFrame(1, true).GetMethod().Name;
                    if (UseNowToString)
                    {
                        message = String.Format("[{0}] [{1}.{2}] {3} TRACE - {4}",
                            _sIncludeFilterName, className, methodName, NowToString(), message);
                    }
                    else
                    {
                        message = String.Format("[{0}] [{1}.{2}] TRACE - {3}", 
                            _sIncludeFilterName, className, methodName, message);
                    }
                    Trace.WriteLine(message);
                }
            }
        }
    }

    [ 그림 1 - Debug 실행 Visual Studio 출력 탭 ]

    그림1과 같이 디버깅시작(F5) 하면 출력탭에 Debug, Trace 클래스 WriteLine 메서드로 출력한 메시지가 보이는 걸 보실 수 있습니다. 프로그램 개발이 완료되어 베포되었을 때 오류가 났을 경우 DebugView로 Debug, Trace 클래스로 작성한 메시지를 볼 수 있습니다.

    Debug

    - Debug 모드일때 디버깅 시작(F5) 하여 실행 하거나 그냥 실행 하였을때 볼 수 있습니다. Release 모드 시에는 해당 클래스 메시지는 보이지 않습니다.

    Toolkit.cs 파일 에서 볼 수 있듯이 DEBUG 일 때만 True 로 설정하여 불 필요한 메소드 호출을 피할 수 있습니다.

    [ 그림 2 - Debug 실행 DebugView ]

    Trace

    - Release 모드일때 실행 하였을 때 볼 수 있습니다. Debug 클래스를 활용한 메시지는 볼 수 없으며 해당 클래스의 메시지만 볼 수 있습니다.

    [ 그림 3 - Release 실행 DebugView ]

    Release 모드에서는 Debug 모드와 다르게 앞에 출력되는 값이 아래와 같이 다릅니다.

    IncludeFilterName

    Debug : UseDebugView

    Release : ApplicationName

    위와 같이 설정하는 이유는 필자는 개발시에 DebugView를 보면서 프로그램에서 버그가 발생하였을 경우 디버깅을 해야 될 상황이 있어 각각의 프로젝트 이름별로 이름을 정합니다. 위와 같이 Toolkit 클래스를 프로젝트별로 만듭니다. 그리하여 접근지정자 또한 Internal 로 지정합니다. 특정 부분에서 에러가 발생하였을 경우 어느모듈에서 발생하는지 파악이 쉽기 때문입니다.

    그러나 실제 운영시(Release)에는 IncludeFilterName 값을 모든 프로젝트의 Toolkit 클래스에 동일하게 적용합니다. 상황에 따라서는 개발시(Debug)에도 동일하게 IncludeFilterName 값을 모든 프로젝트의 Toolkit 클래스에 동일하게 적용이 필요 할 경우도 있습니다.

    금융권같은 경우에는 보안프로그램이 워낙 많기 때문에 DebugView를 실행해보면 1초단위로 엄청나게 많은 로깅메시지가 출력됩니다. 워낙 많은 로깅 메시지가 출력이 되기때문에 작업을 진행하기 힘듭니다.

    [ 그림 4 - DebugView Filter 적용 ]

    그림 4와 같이 Include 항목에 Toolkit.IncludeFilterName에 적용한 값을 입력하고 확인을 누르면 해당 [ApplicationName] 항목이 포함된 항목만 DebugView 로깅메시지가 출력됩니다.

    Include : [ApplicationName] 내용을 포함하고 있는 출력할 메시지

    Exclude : 예) [Test] 내용을 포함하고 있는 제외할 메시지

    [ 그림 5 - DebugView Time Format 적용 전 ]
    [ 그림 6 - DebugView Time Format 적용 후 ]

    그림 5는 Time Format 을 적용 전, 그림 6은 Time Format 적용 후 입니다. Time Format 이 적용 후 시간이 출력 되는걸 볼 수 있습니다.

    DebugView 의 자세한 내용은 최 상단에 링크를 통해 확인해 주시기 바랍니다.

    GitHub Source
    https://github.com/soultomind/Blog/tree/develop/UseDebugView

    '.NET > Tools, Library' 카테고리의 다른 글

    [ILMerge] - 사용하기  (0) 2017.11.24
    [IKVM] - 사용하기  (0) 2017.04.03
    [Style Schemes] - VisualStudio 스타일 Schemes  (1) 2015.10.24

    댓글

Designed by Tistory.