atrace tracing bug workaround for Android 4.4
Summary: Hack to get around un-opened fd_trace_marker for Profilo trace. The workaround assigns a magic fg when it is -1 and uses the magic fd to still continue dumping Profilo trace
@@ -57,10 +57,10 @@ bool atrace_enabled;
namespace {
ssize_t const kAtraceMessageLength = 1024;
+// Magic FD to simply write to tracer logger and bypassing real write
+int const kTracerMagicFd = -100;
-void log_systrace(int fd, const void* buf, size_t count) {
- if (systrace_installed && fd == *atrace_marker_fd && count > 0 &&
- TraceProviders::get().isEnabled(provider_mask.load())) {
+void log_systrace(const void* buf, size_t count) {
const char* msg = reinterpret_cast<const char*>(buf);
EntryType type;
@@ -112,16 +112,27 @@ void log_systrace(int fd, const void* buf, size_t count) {
}
}
}
+
+bool should_log_systrace(int fd, size_t count) {
+ return (
+ systrace_installed && fd == *atrace_marker_fd &&
+ TraceProviders::get().isEnabled(provider_mask.load()) && count > 0);
}
ssize_t write_hook(int fd, const void* buf, size_t count) {
- log_systrace(fd, buf, count);
+ if (should_log_systrace(fd, count)) {
+ log_systrace(buf, count);
+ return count;
+ }
return CALL_PREV(write_hook, fd, buf, count);
}
ssize_t
__write_chk_hook(int fd, const void* buf, size_t count, size_t buf_size) {
- log_systrace(fd, buf, count);
+ if (should_log_systrace(fd, count)) {
+ log_systrace(buf, count);
+ return count;
+ }
return CALL_PREV(__write_chk_hook, fd, buf, count, buf_size);
}
@@ -202,7 +213,13 @@ void installSystraceSnooper(int providerMask) {
throw std::runtime_error("Trace FD not defined");
}
if (*atrace_marker_fd == -1) {
- throw std::runtime_error("Trace FD not valid");
+ // This is a case that can happen for older Android version i.e. 4.4
+ // in which scenario the marker fd is not initialized/opened by Zygote.
+ // Nevertheless for Profilo trace it is not necessary to have an open fd,
+ // since all we really need is to ensure that we 'know' it is marker
+ // fd to continue writing Profilo logs, thus the usage of marker fd
+ // acting really as a placeholder for magic id.
+ *atrace_marker_fd = kTracerMagicFd;
}
}
