• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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