1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstdlib>
17 #include <cinttypes>
18 #include <sys/types.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include "utils/logger.h"
22
23 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
24 static const char PANDA_TRACE_KEY[] = "PANDA_TRACE";
25 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
26 static const char TRACE_MARKER_PATH[] = "/sys/kernel/debug/tracing/trace_marker";
27
28 namespace panda::trace::internal {
29
30 int g_trace_marker_fd = -1;
DoInit()31 bool DoInit()
32 {
33 if (g_trace_marker_fd != -1) {
34 LOG(ERROR, TRACE) << "Already init.";
35 return false;
36 }
37
38 const char *panda_trace_val = std::getenv(PANDA_TRACE_KEY);
39 if (panda_trace_val == nullptr) {
40 return false;
41 }
42
43 if (panda_trace_val != std::string("1")) {
44 LOG(INFO, TRACE) << "Cannot init, " << PANDA_TRACE_KEY << "=" << panda_trace_val;
45 return false;
46 }
47
48 // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg)
49 g_trace_marker_fd = open(TRACE_MARKER_PATH, O_CLOEXEC | O_WRONLY);
50 if (g_trace_marker_fd == -1) {
51 PLOG(ERROR, TRACE) << "Cannot open file: " << TRACE_MARKER_PATH;
52 return false;
53 }
54
55 LOG(INFO, TRACE) << "Trace enabled";
56 return true;
57 }
58
59 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
60 #define WRITE_MESSAGE(...) \
61 do { \
62 ASSERT(g_trace_marker_fd != -1); \
63 if (UNLIKELY(dprintf(g_trace_marker_fd, __VA_ARGS__) < 0)) { \
64 LOG(ERROR, TRACE) << "Cannot write trace event. Try enabling tracing and run app again"; \
65 } \
66 } while (0)
67
DoBeginTracePoint(const char * str)68 void DoBeginTracePoint(const char *str)
69 {
70 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
71 WRITE_MESSAGE("B|%d|%s", getpid(), str);
72 }
73
DoEndTracePoint()74 void DoEndTracePoint()
75 {
76 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
77 WRITE_MESSAGE("E|");
78 }
79
DoIntTracePoint(const char * str,int32_t val)80 void DoIntTracePoint(const char *str, int32_t val)
81 {
82 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
83 WRITE_MESSAGE("C|%d|%s|%d", getpid(), str, val);
84 }
85
DoInt64TracePoint(const char * str,int64_t val)86 void DoInt64TracePoint(const char *str, int64_t val)
87 {
88 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
89 WRITE_MESSAGE("C|%d|%s|%" PRId64, getpid(), str, val);
90 }
91
92 } // end namespace panda::trace::internal
93