• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
18 #define INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
19 
20 #include "perfetto/base/compiler.h"
21 #include "perfetto/base/logging.h"
22 #include "perfetto/tracing/interceptor.h"
23 #include "perfetto/tracing/track_event_state_tracker.h"
24 
25 #include <stdarg.h>
26 
27 #include <functional>
28 #include <map>
29 #include <vector>
30 
31 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
32 #include <io.h>
33 #else
34 #include <unistd.h>
35 #endif
36 
37 #if defined(__GNUC__) || defined(__clang__)
38 #define PERFETTO_PRINTF_ATTR \
39   __attribute__((format(printf, /*format_index=*/2, /*first_to_check=*/3)))
40 #else
41 #define PERFETTO_PRINTF_ATTR
42 #endif
43 
44 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && !defined(STDOUT_FILENO)
45 #define STDOUT_FILENO 1
46 #define STDERR_FILENO 2
47 #endif
48 
49 namespace perfetto {
50 namespace protos {
51 namespace pbzero {
52 class DebugAnnotation_Decoder;
53 class TracePacket_Decoder;
54 class TrackEvent_Decoder;
55 }  // namespace pbzero
56 }  // namespace protos
57 
58 struct ConsoleColor;
59 
60 class PERFETTO_EXPORT ConsoleInterceptor
61     : public Interceptor<ConsoleInterceptor> {
62  public:
63   ~ConsoleInterceptor() override;
64 
65   static void Register();
66   static void OnTracePacket(InterceptorContext context);
67 
68   static void SetOutputFdForTesting(int fd);
69 
70   void OnSetup(const SetupArgs&) override;
71   void OnStart(const StartArgs&) override;
72   void OnStop(const StopArgs&) override;
73 
74   struct ThreadLocalState : public InterceptorBase::ThreadLocalState {
75     ThreadLocalState(ThreadLocalStateArgs&);
76     ~ThreadLocalState() override;
77 
78     // Destination file. Assumed to stay valid until the program ends (i.e., is
79     // stderr or stdout).
80     int fd{};
81     bool use_colors{};
82 
83     // Messages up to this length are buffered and written atomically. If a
84     // message is longer, it will be printed with multiple writes.
85     std::array<char, 1024> message_buffer{};
86     size_t buffer_pos{};
87 
88     // We only support a single trace writer sequence per thread, so the
89     // sequence state is stored in TLS.
90     TrackEventStateTracker::SequenceState sequence_state;
91     uint64_t start_time_ns{};
92   };
93 
94  private:
95   class Delegate;
96 
97   // Appends a formatted message to |message_buffer_| or directly to the output
98   // file if the buffer is full.
99   static void Printf(InterceptorContext& context,
100                      const char* format,
101                      ...) PERFETTO_PRINTF_ATTR;
102   static void Flush(InterceptorContext& context);
103   static void SetColor(InterceptorContext& context, const ConsoleColor&);
104   static void SetColor(InterceptorContext& context, const char*);
105 
106   static void PrintDebugAnnotations(InterceptorContext&,
107                                     const protos::pbzero::TrackEvent_Decoder&,
108                                     const ConsoleColor& slice_color,
109                                     const ConsoleColor& highlight_color);
110   static void PrintDebugAnnotationName(
111       InterceptorContext&,
112       const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
113   static void PrintDebugAnnotationValue(
114       InterceptorContext&,
115       const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
116 
117   int fd_ = STDOUT_FILENO;
118   bool use_colors_ = true;
119 
120   TrackEventStateTracker::SessionState session_state_;
121   uint64_t start_time_ns_{};
122 };
123 
124 }  // namespace perfetto
125 
126 #endif  // INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
127