[고급] 콜 스택, 짭짤하게 활용하기

모든 .NET Framework들은 Common Language Runtime에서 관리하는 콜 스택을 응용프로그램에게 개방합니다. 콜 스택은 반드시 System.Exception에서만 확인할 수 있는 “디버깅 전용” 정보는 아닙니다. 콜 스택을 응용하여 기존에 구현하기 어려웠던 사항 한 가지를 다루어 볼까 합니다.


System.Diagnostic이라는 네임스페이스, 기억하고 계십니까? (처음 들으시는 분들도 적잖으리라 생각합니다.) System.Diagnostic의 클래스들 중 StackTrace와 StackFrame이라는 두 클래스를 사용하여 콜 스택을 검색할 수 있습니다. 콜 스택 검색을 사용하여 Public으로 열려있는 메서드이지만 아무데서나 호출할 수는 없게 보호하는 것이 가능합니다. 다시 말해, 비록 Public으로 열려있는 메서드이지만 호출했을 때 지정한 메서드에서 호출한게 아니면 실행되지 않거나 예외를 Throw하는 것 등이 가능합니다.


콜 스택 검색 기능을 사용하여 원하시는 여러 가지 일을 할 수 있을 것입니다. 하지만 콜 스택의 속성을 정확히 알고 검색하려면 .NET Framework의 동작 원리와 많은 시행 착오가 동반되어야 할 것입니다.


StackTrace 클래스는 콜 스택을 CLR로부터 가져와 인덱스를 기준으로 검색하는 방식을 지원합니다. StackTrace에는 중요한 메서드와 읽기 전용 프로퍼티가 각각 하나씩 있습니다. GetFrame 이라는 메서드와 FrameCount라는 읽기 전용 프로퍼티입니다. FrameCount로 기록된 프레임의 수를 조사할 수 있습니다. 반복문으로 프레임을 하나씩 가져오면 쉽습니다.


StackFrame 클래스는 호출된 “시점”에 관한 모든 정보를 포함하는 클래스입니다. 빌드하는 어셈블리의 설정에 따라서 이 클래스의 능력이 좌우되는데, 디버그 정보를 포함하도록 하는 디버그 모드로 컴파일하여 StackFrame 클래스를 사용한다면 해당 시점과 일치하는 소스 코드 파일 이름, 행 및 열 번호까지 액세스할 수 있습니다. 그러나 디버그 모드가 아니라면 이 기능은 사용할 수 없으며 단지 “시점”에 해당하는 메서드의 정보, IL 코드 및 런타임 코드의 오프셋 정도만을 알 수 있습니다. 이 중에 메서드의 정보를 반환하는 기능을 사용하면 System.Reflection 네임스페이스와 연동하여 해당 메서드를 포함하는 어셈블리까지 훑어 낼 수 있습니다. (.NET Framework의 확장성이란 이런 면에도 있는 것입니다. 저는 System.Data 또는 System.Xml 네임스페이스에 버금가는 확장성이 바로 여기서 등장한다고 봅니다.)


다음의 코드를 살펴보겠습니다.



    internal static bool AssertValidRoute(string expectedMethodName)


    {


      StackTrace tracer = new StackTrace();


      for(int i=0; i<tracer.FrameCount; i++)


       if(tracer.GetFrame(i).GetMethod().Name.Equals(expectedMethodName))


        return true;


      throw new UnauthorizedAccessException(“You cannot access this method.”);


    }


위에서는 아주 간단하게 코드를 작성했습니다. 위의 코드로 특정한 메서드가 호출 스택에 포함되어있는지 확인하는 것으로 조건에 해당되면 정당한 액세스라는 것을 알립니다. 여기에는 몇 가지의 헛점이 존재합니다. 연구해 보시기 바랍니다. ^^

댓글 남기기