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