C/C++에서 Perfetto를 사용한 Android 분석
C/C++에서 Perfetto를 사용한 Android 분석
1. 들어가며
Perfetto 분석이 필요하여, perfetto docs를 뒤지던 중 Perfetto SDK가 있음을 확인했다. 그 전에는 이런 게 있는 줄 몰랐는데 C/C++로 구현할 수 있으면 훨씬 확장성이나 적은 overhead로 구현할 수 있어 잘됐다 싶었다.
2. 환경 설정
일단, 나 같은 경우는 perfetto를 github repository의 submodule로 만들어서 사용했는데, 이 게시글에서는 매우 간단한 버전으로 구성하도록 하겠다.
1
2
mkdir -p perfetto_ex && cd perfetto_ex
git clone https://github.com/google/perfetto -b v50.1
3. 라이브러리 빌드
1
2
3
cd perfetto/examples/sdk
cmake -S . -B build
cmake --build build
이렇게 하면 우리는 이제 리눅스와 안드로이드에서 사용가능한 라이브러리를 빌드한 것이다. 따라서, C/C++ 파일에서 perfetto를 include할 수 있다.
4. C++ 코드 작성
먼저, perfetto_ex 경로로 향해준다.
1
cd ../../../ # perfetto_ex
그 다음, C++ 코드를 작성해준다. 파일이름은 일단 main.cpp로 해두겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// main.cpp
#include <perfetto.h>
#include <fstream>
#include <thread>
#include <chrono>
int main() {
// 1) system trace backend
perfetto::TracingInitArgs args;
args.backends = perfetto::kSystemBackend;
perfetto::Tracing::Initialize(args);
// 2) construct TraceConfig
perfetto::TraceConfig cfg;
cfg.add_buffers()->set_size_kb(16384); // 16MB
// --- android.power ---
{
auto* ds = cfg.add_data_sources();
auto* dsc = ds->mutable_config();
dsc->set_name("android.power");
perfetto::protos::gen::AndroidPowerConfig p;
p.set_battery_poll_ms(250);
// defined in AndroidPowerConfig
// (CHARGE=1, CAPACITY_PERCENT=2, CURRENT=3, CURRENT_AVG=4, VOLTAGE=5 등) :contentReference[oaicite:9]{index=9}
p.add_battery_counters(perfetto::protos::gen::AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
p.add_battery_counters(perfetto::protos::gen::AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
p.add_battery_counters(perfetto::protos::gen::AndroidPowerConfig::BATTERY_COUNTER_CURRENT);
p.add_battery_counters(perfetto::protos::gen::AndroidPowerConfig::BATTERY_COUNTER_VOLTAGE);
p.set_collect_power_rails(true);
p.set_collect_energy_estimation_breakdown(true);
dsc->set_android_power_config_raw(p.SerializeAsString());
}
// --- linux.ftrace ---
{
auto* ds = cfg.add_data_sources();
auto* dsc = ds->mutable_config();
dsc->set_name("linux.ftrace");
perfetto::protos::gen::FtraceConfig f;
f.set_buffer_size_kb(4096); // per-cpu ftrace ring buffer size :contentReference[oaicite:10]{index=10}
f.add_ftrace_events("devfreq/devfreq_frequency");
f.add_ftrace_events("sched/sched_switch");
f.add_ftrace_events("sched/sched_waking");
f.add_ftrace_events("power/cpu_frequency");
f.add_ftrace_events("power/cpu_idle");
dsc->set_ftrace_config_raw(f.SerializeAsString());
}
// 3) session start / termination
auto session = perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
session->Setup(cfg);
session->StartBlocking();
// workload
std::this_thread::sleep_for(std::chrono::seconds(5));
// add workload if you needed
session->StopBlocking();
// 4) save trace output :contentReference[oaicite:12]{index=12}
std::vector<char> trace_data = session->ReadTraceBlocking();
std::ofstream out("./traces.perfetto-trace", std::ios::binary);
out.write(trace_data.data(), static_cast<std::streamsize>(trace_data.size()));
out.close();
return 0;
}
Perfetto 버전마다 함수명이 다를 수 있다.
해당 버전은 v50.1임을 명심한다.
5. CMakeLists 작성
기존에 빌드해두었던 perfetto 라이브러리를 가져와 함께 빌드시켜주기 위해서 이를 위한 CMakeList.txt를 작성하도록 하겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cmake_minimum_required(VERSION 3.13)
project(perfetto_test)
set(CMAKE_CXX_STANDARD 17)
find_package(Threads REQUIRED)
message(STATUS ${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/perfetto/include)
include_directories(${CMAKE_SOURCE_DIR}/perfetto/sdk)
add_library(perfetto STATIC ${CMAKE_SOURCE_DIR}/perfetto/sdk/perfetto.cc)
add_executable(perfetto_test main.cpp)
target_link_libraries(perfetto_test perfetto Threads::Threads)
if(ANDROID)
target_link_libraries(perfetto_test log)
endif()
6. 빌드 및 실행
1
2
3
cmake -S . -B build
cmake --build build --config Release
./build/perfetto_test
이렇게 하면 실행이 가능하다. 빌드 에러가 뜬다면 댓글 부탁드립니다.
그리고 실행 이후에는 traces.perfetto-trace라는 파일이 생기는데, 이 파일을 Perfetto UI에 해당 파일을 삽입하여 값을 확인해볼 수 있다.
관련 게시글
기존에 adb shell에서 perfetto 측정과 분석에 대해서 다룬 적이 있으므로 참고하면 좋다.
또한, 내 github repository에 어떻게 submodule로 구성하여 사용하였는지 예시로 두었기에 확인해보면 좋을 것 같다.
출처