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 <cinttypes>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include "utils/logger.h"
20
21 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
22 static const char PANDA_TRACE_KEY[] = "PANDA_TRACE";
23 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
24 static const char TRACE_MARKER_PATH[] = "/sys/kernel/debug/tracing/trace_marker";
25
26 namespace panda::trace::internal {
27
28 int g_trace_marker_fd = -1;
DoInit()29 bool DoInit()
30 {
31 if (g_trace_marker_fd != -1) {
32 LOG(ERROR, TRACE) << "Already init.";
33 return false;
34 }
35
36 const char *panda_trace_val = std::getenv(PANDA_TRACE_KEY);
37 if (panda_trace_val == nullptr) {
38 return false;
39 }
40
41 if (panda_trace_val != std::string("1")) {
42 LOG(INFO, TRACE) << "Cannot init, " << PANDA_TRACE_KEY << "=" << panda_trace_val;
43 return false;
44 }
45
46 // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg)
47 g_trace_marker_fd = open(TRACE_MARKER_PATH, O_CLOEXEC | O_WRONLY);
48 if (g_trace_marker_fd == -1) {
49 PLOG(ERROR, TRACE) << "Cannot open file: " << TRACE_MARKER_PATH;
50 return false;
51 }
52
53 LOG(INFO, TRACE) << "Trace enabled";
54 return true;
55 }
56
57 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
58 #define WRITE_MESSAGE(...) \
59 do { \
60 ASSERT(g_trace_marker_fd != -1); \
61 if (UNLIKELY(dprintf(g_trace_marker_fd, __VA_ARGS__) < 0)) { \
62 LOG(ERROR, TRACE) << "Cannot write trace event. Try enabling tracing and run app again"; \
63 } \
64 } while (0)
65
DoBeginTracePoint(const char * str)66 void DoBeginTracePoint(const char *str)
67 {
68 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
69 WRITE_MESSAGE("B|%d|%s", getpid(), str);
70 }
71
DoEndTracePoint()72 void DoEndTracePoint()
73 {
74 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
75 WRITE_MESSAGE("E|");
76 }
77
DoIntTracePoint(const char * str,int32_t val)78 void DoIntTracePoint(const char *str, int32_t val)
79 {
80 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
81 WRITE_MESSAGE("C|%d|%s|%d", getpid(), str, val);
82 }
83
DoInt64TracePoint(const char * str,int64_t val)84 void DoInt64TracePoint(const char *str, int64_t val)
85 {
86 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
87 WRITE_MESSAGE("C|%d|%s|%" PRId64, getpid(), str, val);
88 }
89
90 } // end namespace panda::trace::internal
91