blob: c731264cf88913148d0f5392973e159babfbd95b [file] [log] [blame]
Brian Silverman79ec7fc2020-06-08 20:11:22 -05001#include "aos/ftrace.h"
2
Tyler Chatowbf0609c2021-07-31 16:13:27 -07003#include <cstdarg>
4#include <cstdio>
Brian Silverman79ec7fc2020-06-08 20:11:22 -05005
Austin Schuh99f7c6a2024-06-25 22:07:44 -07006#include "absl/flags/flag.h"
7#include "absl/log/check.h"
Austin Schuhc9de0132022-12-26 18:04:53 -08008#include "absl/strings/str_cat.h"
9
Austin Schuh99f7c6a2024-06-25 22:07:44 -070010ABSL_FLAG(bool, enable_ftrace, false,
11 "If false, disable logging to /sys/kernel/tracing/trace_marker");
Austin Schuh27237362021-11-06 16:29:02 -070012
Brian Silverman79ec7fc2020-06-08 20:11:22 -050013namespace aos {
14
Austin Schuhc9de0132022-12-26 18:04:53 -080015namespace {
Austin Schuh3458e492022-12-26 13:41:54 -080016int MaybeCheckOpen(const char *file) {
Austin Schuh99f7c6a2024-06-25 22:07:44 -070017 if (!absl::GetFlag(FLAGS_enable_ftrace)) return -1;
Austin Schuhc9de0132022-12-26 18:04:53 -080018 int result =
19 open(absl::StrCat("/sys/kernel/tracing/", file).c_str(), O_WRONLY);
20 if (result == -1) {
21 result = open(absl::StrCat("/sys/kernel/debug/tracing/", file).c_str(),
22 O_WRONLY);
23 }
24
25 // New kernels prefer /sys/kernel/tracing, and old kernels prefer
26 // /sys/kernel/debug/tracing... When Ubuntu 18.04 and the 4.9 kernel
27 // disappear finally, we can switch fully to /sys/kernel/tracing.
28 PCHECK(result >= 0) << ": Failed to open /sys/kernel/tracing/" << file
29 << " or legacy /sys/kernel/debug/tracing/" << file;
Austin Schuh3458e492022-12-26 13:41:54 -080030 return result;
31}
Austin Schuhc9de0132022-12-26 18:04:53 -080032} // namespace
Austin Schuh3458e492022-12-26 13:41:54 -080033
Austin Schuh27237362021-11-06 16:29:02 -070034Ftrace::Ftrace()
Austin Schuhc9de0132022-12-26 18:04:53 -080035 : message_fd_(MaybeCheckOpen("trace_marker")),
36 on_fd_(MaybeCheckOpen("tracing_on")) {}
Austin Schuh27237362021-11-06 16:29:02 -070037
Brian Silverman79ec7fc2020-06-08 20:11:22 -050038Ftrace::~Ftrace() {
39 if (message_fd_ != -1) {
40 PCHECK(close(message_fd_) == 0);
41 }
42 if (message_fd_ != -1) {
43 PCHECK(close(on_fd_) == 0);
44 }
45}
46
Austin Schuh99f7c6a2024-06-25 22:07:44 -070047void Ftrace::TurnOffOrDie() {
48 CHECK(on_fd_ != -1)
49 << ": Failed to open tracing_on earlier, cannot turn off tracing";
50 char zero = '0';
51 CHECK_EQ(write(on_fd_, &zero, 1), 1) << ": Failed to turn tracing off";
52}
53
Brian Silverman79ec7fc2020-06-08 20:11:22 -050054void Ftrace::FormatMessage(const char *format, ...) {
55 if (message_fd_ == -1) {
56 return;
57 }
58 char buffer[512];
59 va_list ap;
60 va_start(ap, format);
61 const int result = vsnprintf(buffer, sizeof(buffer), format, ap);
62 va_end(ap);
63 CHECK_LE(static_cast<size_t>(result), sizeof(buffer))
64 << ": Format string ended up too long: " << format;
65 WriteMessage(std::string_view(buffer, result));
66}
67
68void Ftrace::WriteMessage(std::string_view content) {
69 if (message_fd_ == -1) {
70 return;
71 }
72 const int result = write(message_fd_, content.data(), content.size());
73 if (result == -1 && errno == EBADF) {
74 // This just means tracing is turned off. Ignore it.
75 return;
76 }
77 PCHECK(result >= 0) << ": Failed to write ftrace message: " << content;
78 CHECK_EQ(static_cast<size_t>(result), content.size())
79 << ": Failed to write complete ftrace message: " << content;
80}
81
82} // namespace aos