Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
TinyInst — 경량 동적 계측 라이브러리 | Kitploit
도구/GitHubGitHub/googleprojectzero/tinyinst
Dynamic Analysis (Sandboxing)Code AnalysisReverse EngineeringDebuggersFuzzingBinary Analysis
GitHubgoogleprojectzero/tinyinst

TinyInst

경량 동적 계측 라이브러리

저장소 보기
1.4k140159일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

TinyInst```

Copyright 2020 Google LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

root@kitploit:~
https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

root@kitploit:~
## TinyInst란 무엇인가요?

TinyInst는 가벼운 동적 계측(dynamic instrumentation) 라이브러리로, 프로세스에서 선택된 모듈만 계측하고 나머지 프로세스는 네이티브로 실행되도록 할 수 있습니다. 이해하기 쉽고, 해킹하기 쉽고, 해킹에 활용하기 쉽도록 설계되었습니다. 모든 대상과 호환되도록 설계되지는 않았습니다(이에 대해서는 나중에 더 설명합니다).

### [DynamoRIO](https://dynamorio.org/) 및 [PIN](https://software.intel.com/en-us/articles/pintool)과 어떻게 비교되나요?

TinyInst는 DynamoRIO 및 PIN과 같은 복잡한 계측 프레임워크를 대체하기 위한 것이 아니라, 더 가벼운 솔루션이 적합한 시나리오를 위한 대안입니다. TinyInst는 대상이 잘 동작한다고 가정합니다(아래에서 설명하는 의미에서). 이는 더 복잡한 프레임워크의 경우와는 다릅니다. 따라서 [이전에 DynamoRIO로 수행된 것처럼](https://www.slideshare.net/MaximShudrak/fuzzing-malware-for-fun-profit-applying-coverageguided-fuzzing-to-find-bugs-in-modern-malware) TinyInst를 악성 코드에 대해 성공적으로 실행하지 못할 것입니다. 반면에, 대상이 계측할 필요가 없는 모듈로 인해 다른 프레임워크에서 작동하지 않고 계측된 모듈이 잘 동작한다면 TinyInst에서는 작동할 수 있습니다. TinyInst에서는 대부분의 프로세스가 네이티브로 실행되므로 프로세스 시작 시간이 더 짧고, 계측이 필요하지 않은 모듈에서 대상 프로세스가 많은 시간을 소비하는 경우 다른 솔루션보다 성능이 뛰어날 수 있습니다.

### [Mesos](https://github.com/gamozolabs/mesos) 및 [TrapFuzz](https://github.com/googleprojectzero/p0tools/tree/master/TrapFuzz)와 어떻게 비교되나요?

TinyInst는 완전한 바이너리 재작성 솔루션으로, 대상 모듈에서 임의의 동작을 변경할 수 있습니다. 예를 들어, 기본 블록(basic block)만이 아니라 에지 커버리지(edge coverage)를 추출할 수 있습니다. 또한 TinyInst는 기본 블록을 식별하기 위해 IDA Pro와 같은 다른 소프트웨어에 의존하지 않습니다.

### TinyInst는 어떤 운영 체제를 지원하나요?

TinyInst는 Windows(x86 및 x64), macOS(x64 및 ARM64), Linux(x64 및 ARM64) 및 Android(ARM64)에서 작동합니다. 각 운영 체제에 대한 추가 참고 사항 및 제한 사항은 해당 디렉토리의 README를 참조하십시오.

### 어떤 대상이 TinyInst와 호환되나요?

TinyInst는 계측된 모든 모듈이 다음 의미에서 잘 동작한다고 가정합니다.

- 자체 수정 코드가 없음
- 스택의 반환 주소를 프로그램이 직접 접근하지 않음
또는/그리고 (설정에 따라)
- 스택 상단보다 낮은 주소(ESP/RSP가 가리키는 주소보다 낮은 주소)에 데이터를 저장하지 않음. 이 조건은 `-stack_offset` 플래그를 사용하여 "(ESP/RSP - arbitrary_offset) 이전에 데이터 없음"으로 완화할 수 있습니다.

TinyInst는 또한 대상 프로세스에 DEP/NX가 활성화되어 있어야 합니다. 이미 활성화되어 있지 않은 경우 `-force_dep` 플래그를 사용하여 강제로 활성화할 수 있습니다. 그러나 대상이 제대로 작동하기 위해 DEP가 꺼져 있어야 하는 드문 경우에는 강제로 활성화하면 오작동할 수 있습니다.

### 성능 오버헤드는 얼마나 되나요?

이미지 디코딩에 대한 초기 측정에 따르면, 기본 TinyInst 설정을 사용하는 잘 동작하는 64비트 대상에서 성능 오버헤드는 클라이언트 없이 약 15%, 예시 커버리지 수집 클라이언트를 사용할 때 약 20%였습니다. 이는 초기 모듈 계측으로 인한 시간 초과를 포함하지 않습니다. 자세한 내용은 아래의 성능 팁을 참조하십시오.

## TinyInst 빌드하기

1. 터미널을 열고 빌드 환경을 설정합니다(예: Windows에서는 vcvars64.bat / vcvars32.bat 실행)

2. 소스가 포함된 디렉토리로 이동합니다

3. 다음 명령을 실행합니다(빌드하려는 IDE 버전 및 플랫폼에 따라 생성기를 변경):

#### Windows```
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build . --config Release

macOS```

mkdir build cd build cmake -G Xcode .. cmake --build . --config Release

root@kitploit:~
#### 리눅스```
mkdir build
cd build
cmake ..
cmake --build . --config Release

Android용 크로스 컴파일```

mkdir build cd build cmake -DCMAKE_TOOLCHAIN_FILE=</path/to/android/ndk>build/cmake/android.toolchain.cmake -DANDROID_NDK=</path/to/android/ndk> -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM= .. cmake --build . --config Release

root@kitploit:~
참고 #1: 64비트 빌드는 Windows 및 Linux 운영 체제에서 32비트 타겟에도 실행됩니다.

참고 #2: 환경이 제대로 설정되지 않았거나 라이브러리가 누락되어 64비트 Windows에서 32비트 빌드를 만드는 데 문제가 있습니까? cmake --build를 실행하는 대신 생성된 .sln 파일을 Visual Studio에서 열고 거기서 빌드하세요. 또한 64비트 빌드는 32비트 타겟에서 작동하므로 32비트 빌드를 만들 필요가 없을 수 있습니다.

## TinyInst 사용하기

TinyInst는 주로 다른 프로그램 내에서 라이브러리로 사용되도록 설계되었습니다.

TinyInst 클라이언트는 TinyInst 클래스의 서브클래스로 작성됩니다. 그런 다음 클라이언트는 필요한 API 메서드를 재정의할 수 있습니다. API 메서드는 아래에 정의되어 있습니다.

클라이언트가 생성된 후에는 명령줄 옵션을 사용하여 초기화해야 합니다.

`void init(int argc, char **argv);`

명령줄 옵션은 아래에 정의되어 있으며, 클라이언트는 자신만의 옵션을 정의할 수도 있습니다. 그런 다음 계측된 프로그램을 실행하고 제어하려면 다음 함수를 사용할 수 있습니다.

`DebuggerStatus Run(int argc, char **argv, uint32_t timeout);`
`DebuggerStatus Attach(unsigned int pid, uint32_t timeout);`

이 함수들은 프로그램을 실행하거나(지정된 명령줄 사용) 이미 실행 중인 프로그램에 연결합니다. 타겟 메서드가 지정되지 않은 경우, 타겟은 프로그램이 종료되거나, 충돌하거나, 제한 시간(밀리초 단위)이 만료될 때까지 계속 실행됩니다. 타겟 메서드가 정의된 경우 TinyInst는 타겟 메서드에 진입할 때마다 및 타겟 메서드가 반환될 때마다 반환되어, 호출자가 추가 작업을 수행할 수 있도록 합니다.

`Run` 및 `Attach`가 타겟 프로세스가 계속 실행 중인 상태에서 반환되면 다음 함수를 사용하여 프로세스를 종료하거나 계속 실행할 수 있습니다.

`DebuggerStatus Kill();`

`DebuggerStatus Continue(uint32_t timeout);`

TinyInst는 예제 커버리지 바이너리와 함께 제공되며, 다음과 같이 호출할 수 있습니다.

`<options> -- <target command line>`

Windows 예제:

`litecov.exe -instrument_module notepad.exe -coverage_file coverage.txt -- notepad.exe`

## 계측 API

### 디버거 이벤트 콜백

이 콜백은 정보 제공용이며, 클라이언트는 이 동안 계측된 코드를 내보내면 안 됩니다. 클라이언트는 이러한 이벤트를 직접 처리하기 전에 상위 클래스에 정의된 동일한 핸들러를 호출해야 합니다.

`OnProcessCreated`
타겟 프로세스가 생성되거나 연결될 때 호출됩니다.

`OnProcessExit`
타겟 프로세스가 종료될 때 호출됩니다.

`OnProcessEntrypoint`
프로세스(메인 바이너리)의 진입점에 도달했을 때 호출됩니다.

`OnTargetMethodReached`
타겟 메서드가 정의된 경우, 타겟 메서드에 처음 도달했을 때 호출됩니다.

`OnModuleLoaded`
모듈이 로드될 때 호출됩니다. 계측된 모듈뿐만 아니라 모든 모듈에 대해 호출됩니다.

`OnModuleUnloaded`
모듈이 언로드될 때 호출됩니다. 계측된 모듈뿐만 아니라 모든 모듈에 대해 호출됩니다.

`OnException`
예외가 발생했을 때 호출됩니다. 클라이언트는 예외가 처리된 경우 true를 반환하거나 부모 클래스의 동일한 메서드 결과를 반환해야 합니다.

### 계측 콜백

이 콜백 중에 클라이언트는 `WriteCode()`를 호출하여 타겟에 코드를 추가할 수 있습니다. 클라이언트는 삽입된 코드에서 클로버된 레지스터 및 플래그와 같은 컨텍스트를 저장하고 복원해야 합니다.

`InstrumentBasicBlock`
특정 기본 블록에서 실행될 코드를 삽입하는 데 사용할 수 있습니다.

`InstrumentEdge`
특정 엣지에서 실행될 코드를 삽입하는 데 사용할 수 있습니다. 참고: 성능상의 이유로 이 콜백은 비결정적 엣지(즉, 조건부 점프) 및 간접 점프/호출(예: `call rax`)에 대해서만 내보내집니다. 이전 기본 블록이 주어졌을 때 다음 기본 블록이 항상 알려진 엣지(예: `jmp offset`, `call offset`)에 대해서는 콜백이 내보내지지 않습니다.

`InstrumentInstruction`
명령어를 수정하거나 그 앞에 코드를 삽입하는 데 사용할 수 있습니다. 반환 코드에 따라 원래 명령어는 콜백 후에 내보내지거나 내보내지지 않습니다.

### 기타 콜백

`OnModuleEntered`
제어 흐름이 다른 모듈에서 계측된 모듈로 전송될 때 호출됩니다.

`OnModuleInstrumented`
모듈이 계측될 때 호출됩니다. 이는 일반적으로 프로세스 진입점에 도달했을 때(타겟 메서드가 정의되지 않은 경우) 또는 타겟 메서드에 도달했을 때(정의된 경우) 발생합니다. 클라이언트는 여기에서 계측 관련 데이터를 초기화할 수 있습니다.

`OnModuleUninstrumented`
계측 데이터가 더 이상 유효하지 않아 지워져야 할 때 호출됩니다. 기본적으로 계측은 모듈 언로드/재로드에 걸쳐 지속되므로, 이는 모듈이 언로드되는 것과 동일하지 않습니다. 이 콜백은 클라이언트의 계측 관련 데이터를 지우는 데 사용될 수 있습니다.

### 훅 API

위에 문서화된 범용 API 외에도 TinyInst는 개별 함수의 동작을 검사하고 수정하는 데 더 적합한 훅 API도 구현합니다. 이 API는 [별도 페이지](https://github.com/googleprojectzero/TinyInst/blob/master/hook.md)에 문서화되어 있습니다.

## 명령줄 옵션

### 계측 관련

`-instrument_module [모듈 이름]` 계측할 모듈을 지정합니다. 여러 `-instrument_module` 옵션을 지정하여 여러 모듈을 계측할 수 있습니다.

`-instrument_transitive [모듈 이름]` `-instrument_module`과 유사하지만, 다른 계측된 모듈에서 입력된 코드만 계측된 상태로 실행됩니다. 주로 module1->module2->module1과 같은 호출에 대한 최적화로 사용되며, module2 전체를 계측하는 것이 중요하지 않지만 module2->module1 항목이 속도 저하를 유발하는 경우에 사용됩니다.

`-indirect_instrumentation [none|local|global|auto]` 간접 점프/호출에 사용할 계측 방법입니다.

`-patch_return_addresses` - 반환 주소를 원래 값으로 대체하여, `-indirect_instrumentation`으로 지정된 방법을 사용하여 반환을 계측하게 합니다.

`-generate_unwind` - 계측된 코드에 대한 스택 풀기 데이터를 생성합니다(더 빠른 C++ 예외 처리용). 일부 구형 Windows 버전에서는 제대로 작동하지 않을 수 있습니다.

`-persist_instrumentation_data` (기본값 = true) 모듈 언로드/재로드 시 모듈을 재계측하지 않습니다. 모듈이 이전에 로드된 동일한 주소에 로드된 경우에만 작동합니다.

`-instrument_cross_module_calls` (기본값=true) 여러 `-instrument_module` 모듈이 지정되고 하나가 다른 모듈을 호출하는 경우, 예외(속도 저하 유발)를 발생시키지 않고 다른 모듈의 계측된 코드로 점프합니다.

`-stack_offset` (기본값=0) 스택에 컨텍스트를 저장할 때, 스택 상단(스택 포인터 이전)에 이 바이트 수만큼 변경하지 않고 남깁니다.

`-patch_module_entries [off|data|code|all]` 이전에 감지된 진입점에 대한 포인터를 검색하고 이를 계측된 대응물로 대체하여 과도한 모듈 진입으로 인한 속도 저하를 해결하려고 시도합니다. 이 플래그의 값은 이러한 포인터를 검색할 위치를 제어합니다. 경고: 이 기능을 활성화하면 타겟에 불안정성이 발생할 수 있습니다.

### 디버깅 관련

`-trace_debug_events` - 디버거 이벤트(모듈 로드, 예외 등)를 출력합니다.

`-trace_basic_blocks` - 기본 블록이 실행될 때 출력합니다.

`-trace_module_entries` - 계측된 코드로의 모든 진입을 출력합니다.

`-trace_syscalls` - [Linux/Android 전용] 클라이언트가 `OnSyscall()` / `OnSyscallEnd()` 콜백을 통해 시스템 콜 시작/종료 이벤트를 수신할 수 있도록 합니다.

`-full_address_map` - 계측된 코드의 주소에서 원래 코드의 주소로의 명령어 수준 맵을 유지합니다. 메모리 사용량이 많지만 디버깅에 유용합니다.

### 타겟 메서드 및 지속성

TinyInst는 사용자가 타겟 메서드를 정의할 수 있도록 합니다. 타겟 메서드가 정의된 경우, 타겟 메서드에 처음 도달할 때까지 코드가 계측되지 않습니다(모든 것이 네이티브로 실행됨). 또한 TinyInst는 타겟 메서드 진입 및 종료 시 실행을 중단합니다.

`-target_module` - 타겟 메서드를 포함하는 모듈

`-target_method` - 타겟 메서드의 이름입니다. 타겟 메서드가 내보내지거나 타겟 모듈에 대한 심볼이 있는 경우에만 작동합니다.

`-target_offset` - 타겟 메서드를 이름으로 지정할 수 없는 경우 사용합니다. 모듈 베이스에서 타겟 메서드의 상대 주소입니다.

`-loop` - 이 플래그가 지정되면 TinyInst는 타겟 메서드를 무한 루프로 실행합니다(또는 Kill()이 호출되거나 다른 이유로 프로세스가 종료될 때까지). 함수 인수는 반복 간에 저장되고 복원됩니다. 주로 퍼징을 위한 지속성을 강제하는 데 사용됩니다.

`-nargs` - 반복 간에 저장할 타겟 메서드 인수의 개수입니다. `-loop`와 함께 사용됩니다.

`-callcon [ms64|stdcall|fastcall|thiscall]` - 타겟 메서드가 사용하는 호출 규칙입니다. `-loop`와 함께 사용됩니다.

### 기타

`-target_env key=value` - [현재 macOS 및 Linux/Android 전용] 타겟 프로세스에 전달할 추가 환경 변수를 지정합니다. 여러 환경 변수를 전달하려면 여러 `-target_env` 옵션을 지정할 수 있습니다.

`-force_dep` - [Windows 전용] 타겟 프로세스에 대해 DEP를 강제로 활성화합니다.

## 커버리지 모듈

TinyInst는 (예제) 커버리지 모듈인 `LiteCov`와 함께 제공됩니다. 커버리지 모듈은 기본 블록 또는 엣지 커버리지를 수집할 수 있습니다(`-covtype` 플래그로 제어). 또한 `-cmp_coverage` 플래그를 지정하여 "비교" 커버리지(cmp/sub 명령어에서 일치하는 바이트 수 계산)를 추출할 수 있습니다.

커버리지 모듈의 특별한 기능은 타겟 프로세스의 커버리지 버퍼가 처음에 읽기 전용으로 할당되어, 새로운 커버리지가 처음 발생할 때 예외를 발생시킨다는 점입니다. 특정 커버리지 하위 집합을 무시하는 옵션과 결합하여, 주어진 입력으로 타겟을 실행했을 때 새로운 커버리지가 발생했는지 여부를 빠르게 쿼리할 수 있습니다.

## TinyInst 작동 방식

TinyInst는 사용자 정의 디버거 위에 구축됩니다. 디버거는 로드되는 모듈, 중단점 적중, 예외 발생 등의 이벤트에 대해 타겟 프로세스를 감시합니다. 디버거는 또한 타겟 메서드가 지정된 경우 중단점 및 지속성을 구현합니다.

계측할 모듈이 로드되면 초기에는 다음과 같은 방식으로 "계측"됩니다.

- 모듈의 모든 실행 가능한 영역은 다른 권한(읽기/쓰기)은 원래대로 유지하면서 실행 불가능으로 표시됩니다. 이렇게 하면 제어 흐름이 계측된 모듈에 도달할 때마다 예외가 발생하며, 이는 디버거에 의해 포착되고 처리됩니다.

- 원래 모듈 주소 범위의 2GB 이내에 실행 가능한 메모리 영역이 할당됩니다. 여기에 모듈의 계측/재작성된 코드가 배치됩니다. 2GB는 [rip+offset] 형태의 주소 지정을 사용하는 모든 명령어를 [rip+fixed_offset]으로 대체할 수 있게 하므로 중요합니다.

계측된 모듈에 진입할 때마다(처음이든 이후든), 적중된 기본 블록이 계측되며, 조건부 분기 및 직접 호출 및 점프(예: jmp offset, call offset)를 재귀적으로 따라가면서 안정적으로 발견할 수 있는 모든 기본 블록도 함께 계측됩니다.

이것으로 계측된 코드를 실행하기에 충분합니다. 그 이유는 다음과 같습니다.

- 모든 직접 점프/호출은 계측된 코드의 올바른 위치에 도달합니다.

- 모든 간접 점프/호출(예: call rax)은 원래 코드 위치에 도달하여 예외가 발생하며, 디버거가 명령 포인터를 계측된 코드의 해당 위치로 대체하여 해결합니다.

하지만 작동하긴 하지만, 계측된 모듈 내에 대상이 있는 모든 간접 호출/점프에서 예외가 발생합니다. 예외 처리는 느리므로, 간접성이 많은 대상(예: C++의 가상 메서드, 함수 포인터)을 계측하는 것은 추가 계측 없이는 느릴 것입니다.

### 간접 호출 및 점프 계측

TinyInst는 간접 호출 및 점프를 계측하여 (이미 확인된) 간접 대상에 대한 예외를 피할 수 있습니다. 계측된 호출/점프는 원래 대상으로 점프하는 대신 스텁의 연결 리스트의 헤드로 점프합니다. 각 스텁에는 (original_target, translated_target) 쌍이 포함됩니다. 점프/호출 대상이 original_target과 일치하는지 테스트하고, 일치하면 제어 흐름이 translated_target으로 전달됩니다. 그렇지 않으면 다음 스텁으로 점프합니다. 리스트 끝에 도달하면 점프/호출 대상을 이전에 본 적이 없음을 의미합니다. 이는 디버거에 의해 포착되는 중단점을 발생시키며, 디버거는 다른 스텁을 생성하여 리스트에 삽입함으로써 해결합니다.

이 메커니즘은 두 가지 방식으로 구현될 수 있습니다.
- 호출 사이트별(로컬) 리스트
- 모든 간접 점프/호출이 사용하는 전역 해시 테이블

전역 해시 테이블은 더 나은 성능을 제공합니다. 로컬(호출 사이트별 리스트)을 사용하면 간접 호출/점프 시 올바른 엣지(올바른 소스 주소 포함)를 얻을 수 있습니다.

최신 Windows에서는 CFG로 인해 모든 간접 점프/호출이 동일한 위치에서 발생하므로, CFG로 컴파일된 바이너리에서는 (어떤 종류의 특별한 처리 없이는) 정확한 엣지를 얻는 것이 불가능합니다. 이것이 성능 이점과 함께 TinyInst에서 간접 호출/점프를 처리하는 기본 방법으로 전역 해시 리스트를 사용하는 이유입니다.

### 반환 주소 패칭

기본적으로 계측된 코드에서 호출이 발생할 때 기록되는 반환 주소는 *계측된 코드*의 다음 명령어입니다. 이는 대부분의 경우 올바르게 작동하지만, 타겟 프로세스가 반환 이외의 목적으로 반환 주소에 접근하는 경우 문제가 발생할 수 있습니다. 주목할만한 예로는 64비트 운영 체제에서 예외 처리 중 스택 풀기가 있습니다. 따라서 예외를 잡아야 하는 타겟은 기본적으로 TinyInst에서 올바르게 작동하지 않습니다.

이는 대부분의 경우 `-generate_unwind` 플래그를 추가하여 해결할 수 있으며, 이 플래그는 TinyInst가 타겟 프로세스에 대한 스택 풀기/예외 처리 메타데이터를 생성하고 등록하도록 합니다. `-generate_unwind`는 UNWIND_INFO 버전 2가 필요하므로 일부 구형 Windows 버전에서는 올바르게 작동하지 않을 수 있습니다.

TinyInst는 또한 호출이 발생할 때마다 반환 주소를 계측되지 않은 코드의 해당 값으로 다시 쓰는 옵션(`-patch_return_addresses` 플래그로 노출됨)이 있습니다. 그러나 이 옵션은 계측되지 않은 모듈에서 계측된 모듈로의 모든 반환(뒤로 엣지)에서 컨텍스트 전환을 발생시키므로 상당한 오버헤드를 발생시킵니다.

## 성능 팁

TinyInst에서 가장 큰 오버헤드는 계측되지 않은 모듈에서 계측된 모듈로 진입할 때마다 예외가 발생하는 데서 비롯됩니다. `-trace_module_entries` 플래그를 사용하여 이러한 예외가 트리거되는 것을 볼 수 있습니다. 가능하면 간접 점프/호출 계측을 사용하고, 가능하면 반환 계측을 사용하지 않아야 합니다. TinyInst는 합리적으로 자체 포함된 모듈(또는 모듈 그룹)에서 가장 잘 작동합니다. 예를 들어 모듈 A와 B가 있고 A가 B를 자주 호출하지만 B만 계측된 경우, 많은 속도 저하가 발생합니다. A와 B를 모두 계측하면 더 나은 성능을 얻을 수 있습니다.

## 디버깅 팁

`-trace_basic_blocks`를 사용하여 기본 블록이 실행되는 것을 볼 수 있습니다. 계측된 코드의 주소와 계측되지 않은 코드의 해당 주소를 모두 볼 수 있습니다.

충돌이 발생할 때 프로그램 상태를 검사하려면 OnException() 콜백을 사용하십시오.

## 면책 조항

이것은 공식 Google 제품이 아닙니다.
도구 다운로드