Enable On‑Device Systrace for Android Without a PC and Capture Full Call Traces
This article explains how Android's built‑in Trace infrastructure can be leveraged on the device itself—by modifying native tag variables and hooking write calls—to run systrace without a PC, automatically instrument methods, and export data for Perfetto analysis.
Background
Android processes UI events on a single UI thread. Any long‑running operation blocks subsequent work, causing the app to appear frozen. Identifying slow methods is essential for performance debugging.
Simple timing and its limits
Adding timestamps at method entry and exit (e.g., System.currentTimeMillis()) measures only application‑level code and cannot capture Android system calls. Android already provides trace points via the Trace class, which can be collected with the systrace tool to produce an HTML timeline.
Drawbacks of traditional systrace
Requires a PC connection and command‑line invocation.
Developers must manually insert Trace.beginSection and Trace.endSection, which is impractical for production where hot spots are unknown.
Running systrace on the device
Systrace gathers two kinds of data:
Java and native function calls recorded by the Trace class (written to trace_marker).
Kernel‑level events collected via ftrace.
By setting the appropriate trace tag directly on the device, the need for a PC is eliminated.
Enabling tags without source changes
The Trace.beginSection implementation checks sEnabledTags via nativeGetEnabledTags(). To enable a tag, the native variable atrace_enabled_tags in libcutils.so (or libutils.so on older Android versions) must be modified. The following code loads the library with dlopen, locates the symbol, and writes the desired tag value.
std::string lib_name("libcutils.so");
std::string enabled_tags_sym("atrace_enabled_tags");
if (sdk < 18) {
lib_name = "libutils.so";
enabled_tags_sym = "_ZN7android6Tracer12sEnabledTagsE";
}
void* handle;
if (sdk < 21) {
handle = dlopen(lib_name.c_str(), RTLD_LOCAL);
} else {
handle = dlopen(nullptr, RTLD_GLOBAL);
}
// reinterpret_cast to a pointer to std::atomic<uint64_t>
atrace_enabled_tags = reinterpret_cast<std::atomic<uint64_t>*>(dlsym(handle, enabled_tags_sym.c_str()));Retrieving trace data
The native side writes to trace_marker via the write system call. By obtaining the file‑descriptor pointer ( atrace_marker_fd) and hooking write, raw strings such as "B|pid|name" can be captured, expanded to the full systrace line format, and saved to a file. The file can then be fed to systrace or Perfetto with the --from-file option to generate an HTML view.
void atrace_begin_body(const char* name) {
char buf[ATRACE_MESSAGE_LENGTH];
int len = snprintf(buf, sizeof(buf), "B|%d|%s", getpid(), name);
if (len >= (int)sizeof(buf)) {
ALOGW("Truncated name in %s: %s
", __FUNCTION__, name);
len = sizeof(buf) - 1;
}
write(atrace_marker_fd, buf, len);
}Automatic instrumentation
Manually inserting sections for every method is infeasible in large projects. The approach used by Tencent Matrix generates a compact methodId and passes it to Trace.beginSection, staying within the length limit. Exceptions must also call Trace.endSection to avoid unmatched sections, which would appear as “Did not Finish” entries in the trace.
Conclusion
By leveraging Android’s built‑in Trace mechanism, enabling tags on‑device, and hooking the write path, developers can capture complete call‑chain timelines without a PC. This makes it possible to diagnose intermittent or hidden performance stalls in production environments.
References
https://github.com/facebookincubator/profilo.git
https://github.com/Tencent/matrix.git
https://linux.cn/article-9838-1.html
https://segmentfault.com/a/1190000021327942
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
