1P by neo 5일전 | favorite | 댓글 1개

FlowTracker: Java 프로그램의 데이터 흐름 추적

FlowTracker는 Java 에이전트로, 프로그램이 데이터를 읽고, 조작하고, 쓰는 방식을 추적함. 이를 통해 파일 및 네트워크 I/O를 확인하고, 입력과 출력을 연결하여 출력이 어디에서 왔는지 보여줌. 이를 통해 Java 프로그램의 출력이 무엇을 의미하는지 이해할 수 있음.

데모

Spring PetClinic은 Spring 프레임워크의 데모 애플리케이션임. FlowTracker의 기능을 보여주기 위해 PetClinic이 HTTP 요청을 처리하고 템플릿과 데이터베이스에서 HTML 페이지를 생성하는 과정을 관찰함. 브라우저에서 데모를 실행하거나 비디오를 시청할 수 있음.

  • HTTP 처리: FlowTracker는 어떤 코드가 어떤 출력을 생성했는지 보여줌. 예를 들어, "HTTP/1.1" 또는 HTTP 헤더를 클릭하면, 이 부분이 org.apache.coyote 패키지의 클래스에 의해 생성되었음을 알 수 있음.
  • Thymeleaf 템플릿: 프로그램이 읽은 입력(HTML 템플릿)이 출력과 어떻게 연결되는지 보여줌. HTML 태그 이름을 클릭하면 해당 부분이 layout.html 파일에서 왔음을 알 수 있음.
  • 데이터베이스: HTML 페이지의 테이블에 있는 정보가 데이터베이스에서 왔음을 보여줌. 예를 들어, 테이블의 George를 클릭하면 해당 값이 데이터베이스에서 왔음을 알 수 있음.

이 데모는 인메모리 데이터베이스를 사용하여 SQL 스크립트까지 추적할 수 있음. MySQL 데이터베이스를 사용할 경우, 데이터베이스 연결까지 추적할 수 있음.

사용법

FlowTracker는 현재 개념 증명 단계에 있으며, 모든 프로그램에서 잘 작동하지 않을 수 있음. 또한 많은 오버헤드를 추가하여 프로그램 실행 속도를 느리게 만듦. FlowTracker 에이전트 jar 파일을 다운로드하고 Java 명령줄에 추가하여 사용함.

내부 작동 방식

간단한 설명

FlowTracker는 클래스 파일(bytecode)에 코드를 주입하여 메모리 내 데이터와 그 출처를 추적함. 주로 텍스트 및 바이너리 데이터(String, char 및 byte 배열)를 추적함.

  • JDK 메서드 호출을 FlowTracker의 메서드 호출로 대체함.
  • JDK의 주요 위치에 코드를 주입하여 입력과 출력을 추적함.
  • 메서드 내에서 로컬 변수와 스택의 값을 추적하기 위해 데이터 흐름 분석과 더 깊은 계측을 수행함.
  • 메서드 호출 전후 및 메서드 시작과 끝에 코드를 추가하여 메서드 인수와 반환 값을 추적함.

데이터 모델: Tracker

FlowTracker의 데이터 모델의 핵심 클래스와 개념:

  • Tracker: 추적 객체의 내용과 출처에 대한 정보를 보유함.
    • content: 데이터를 통과한 내용. 예: InputStream 또는 OutputStream을 통과한 모든 바이트.
    • source: 다른 트래커의 소스 범위에 대한 내용의 범위를 연결함.
  • TrackerRepository: 흥미로운 객체와 그 트래커를 연결하는 글로벌 맵을 보유함.
  • TrackerPoint: 단일 원시 값을 나타내는 트래커의 위치를 가리킴.

기본 계측

Trackers를 최신 상태로 유지하기 위해 특정 JDK 메서드 호출 시 FlowTracker의 hook 메서드 호출을 삽입함. 예를 들어, System.arraycopy 호출을 com.coekie.flowtracker.hook.SystemHook.arraycopy 호출로 대체함.

원시 값, 데이터 흐름 분석

원시 값을 추적하는 것은 더 큰 도전임. 예를 들어, byte 값을 추적하기 위해 메서드 내에서 로컬 변수에 트래커를 저장함.

메서드 호출

원시 값이 메서드 호출의 인수와 반환 값으로 다른 메서드로 흐르는 것을 모델링함. Invocation을 사용하여 인수와 반환 값의 PointTracker를 저장함.

코드 자체를 출처로 사용

코드 자체에서 오는 값(예: 원시 및 String 상수)을 추적함. 각 클래스에 대한 트래커를 생성하고, 상수가 참조될 때 해당 트래커를 참조함.

String 리터럴

String 리터럴을 새로 복사하고, String의 내용을 ClassOriginTracker와 연결함. 예를 들어, String s = "abc";String s = StringHook.constantString("abc", 1234, 81);로 재작성됨.

추적되지 않은 값에 대한 대체 방법

프로그램의 모든 값을 추적하지 않음. 추적되지 않은 값이 추적해야 하는 위치에 도달하면, 이를 상수와 유사하게 처리함.

GN⁺의 정리

  • FlowTracker는 Java 프로그램의 데이터 흐름을 추적하여 프로그램의 출력을 이해하는 데 도움을 줌.
  • Spring PetClinic 데모를 통해 HTTP 요청 처리, 템플릿 사용, 데이터베이스 연동을 시각적으로 확인할 수 있음.
  • 현재 개념 증명 단계로, 모든 프로그램에서 잘 작동하지 않을 수 있으며, 성능 오버헤드가 큼.
  • 데이터 흐름 분석과 메서드 호출 추적을 통해 원시 값과 객체의 출처를 추적함.
  • 유사한 기능을 가진 도구로는 Dynatrace, New Relic 등이 있음.
Hacker News 의견
  • Clojure용 FlowStorm이라는 도구를 소개함

    • 공식 Clojure 컴파일러를 포크하여 추가 바이트코드를 삽입함
    • 대부분의 값이 불변이므로 포인터를 유지하여 스냅샷을 찍을 수 있음
    • 웹 앱 디버깅 데모 링크 제공: FlowStorm 데모
  • Java/JVM 생태계의 도구가 매우 훌륭함을 칭찬함

    • jitwatch와 비슷한 수준으로 감명받음
    • FlowTracker가 taint 분석을 연상시킴
    • 관련 키워드: "dynamic taint tracking/analysis"
    • 관련 프로젝트 링크:
  • HTML 요소를 SQL 문장까지 추적하는 데모에 감명받음

    • 이런 도구가 버그 해결의 첫 번째 방어선이 될 수 있을 것임
  • Smalltalk 환경을 연상시킴

    • 모든 객체와 메시지를 추적하고 상호작용할 수 있음
  • 데모 비디오가 매우 유용함을 강조함

    • 낯선 코드베이스를 탐색할 때 유용할 것임
  • HTML 소스 맵과 유사한 개념을 실험한 경험을 공유함

    • 웹 개발 도구가 이러한 전체 스택 속성에서 큰 혜택을 받을 것임
    • 기존 프레임워크에 통합하는 것이 큰 도전임
    • 관련 프로젝트 링크: HTML Source Maps
  • Eve-lang 데모와 유사함을 언급함

  • SQL 인젝션을 동적으로 찾는 도구와 유사한 논문을 기억함

  • 인터넷 상의 데이터를 추적하는 비전을 가졌던 경험을 공유함

    • 이미지의 출처나 문자열의 경로를 추적하는 방향으로 나아가는 단계임
  • VSCode와 프로젝트에서 이 도구를 사용해 보려는 시도에 감사함

    • 현재는 중단했지만, 다시 시도해 볼 계획임