| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef SRC_TRACED_PROBES_FTRACE_FTRACE_PROCFS_H_ |
| #define SRC_TRACED_PROBES_FTRACE_FTRACE_PROCFS_H_ |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "perfetto/ext/base/scoped_file.h" |
| |
| namespace perfetto { |
| |
| constexpr std::string_view kKretprobeDefaultMaxactives = "1024"; |
| |
| class FtraceProcfs { |
| public: |
| static const char* const kTracingPaths[]; |
| |
| // Tries creating an |FtraceProcfs| at the standard tracefs mount points. |
| // Takes an optional |instance_path| such as "instances/wifi/", in which case |
| // the returned object will be for that ftrace instance path. |
| static std::unique_ptr<FtraceProcfs> CreateGuessingMountPoint( |
| const std::string& instance_path = ""); |
| |
| static std::unique_ptr<FtraceProcfs> Create(const std::string& root); |
| |
| static int g_kmesg_fd; |
| |
| explicit FtraceProcfs(const std::string& root); |
| virtual ~FtraceProcfs(); |
| |
| // Set the filter for syscall events. If empty, clear the filter. |
| bool SetSyscallFilter(const std::set<size_t>& filter); |
| |
| // Enable the event under with the given |group| and |name|. |
| bool EnableEvent(const std::string& group, const std::string& name); |
| |
| // Create the kprobe event for the function |name|. The event will be in |
| // |group|/|name|. Depending on the value of |is_retprobe|, installs a kprobe |
| // or a kretprobe. |
| bool CreateKprobeEvent(const std::string& group, |
| const std::string& name, |
| bool is_retprobe); |
| |
| // Remove kprobe event from the system |
| bool RemoveKprobeEvent(const std::string& group, const std::string& name); |
| |
| // Read the "kprobe_profile" file. |
| std::string ReadKprobeStats() const; |
| |
| // Disable the event under with the given |group| and |name|. |
| bool DisableEvent(const std::string& group, const std::string& name); |
| |
| // Returns true if the event under the given |group| and |name| exists and its |
| // enable file is writeable. |
| bool IsEventAccessible(const std::string& group, const std::string& name); |
| |
| // Disable all events by writing to the global enable file. |
| bool DisableAllEvents(); |
| |
| // Read the format for event with the given |group| and |name|. |
| // virtual for testing. |
| virtual std::string ReadEventFormat(const std::string& group, |
| const std::string& name) const; |
| |
| virtual std::string ReadPageHeaderFormat() const; |
| |
| std::string GetCurrentTracer(); |
| // Sets the "current_tracer". Might fail with EBUSY if tracing pipes have |
| // already been opened for reading. |
| bool SetCurrentTracer(const std::string& tracer); |
| // Resets the "current_tracer" to "nop". |
| bool ResetCurrentTracer(); |
| bool AppendFunctionFilters(const std::vector<std::string>& filters); |
| bool ClearFunctionFilters(); |
| bool AppendFunctionGraphFilters(const std::vector<std::string>& filters); |
| bool ClearFunctionGraphFilters(); |
| |
| // Get all triggers for event with the given |group| and |name|. |
| std::vector<std::string> ReadEventTriggers(const std::string& group, |
| const std::string& name) const; |
| |
| // Create an event trigger for the given |group| and |name|. |
| bool CreateEventTrigger(const std::string& group, |
| const std::string& name, |
| const std::string& trigger); |
| |
| // Remove an event trigger for the given |group| and |name|. |
| bool RemoveEventTrigger(const std::string& group, |
| const std::string& name, |
| const std::string& trigger); |
| |
| // Remove all event trigger for the given |group| and |name|. |
| bool RemoveAllEventTriggers(const std::string& group, |
| const std::string& name); |
| |
| // Sets up any associated event trigger before enabling the event |
| bool MaybeSetUpEventTriggers(const std::string& group, |
| const std::string& name); |
| |
| // Tears down any associated event trigger after disabling the event |
| bool MaybeTearDownEventTriggers(const std::string& group, |
| const std::string& name); |
| |
| // Returns true if rss_stat_throttled synthetic event is supported |
| bool SupportsRssStatThrottled(); |
| |
| // Read the printk formats file. |
| std::string ReadPrintkFormats() const; |
| |
| // Opens the "/per_cpu/cpuXX/stats" file for the given |cpu|. |
| base::ScopedFile OpenCpuStats(size_t cpu) const; |
| |
| // Read the "/per_cpu/cpuXX/stats" file for the given |cpu|. |
| std::string ReadCpuStats(size_t cpu) const; |
| |
| // Set ftrace buffer size in pages. |
| // This size is *per cpu* so for the total size you have to multiply |
| // by the number of CPUs. |
| bool SetCpuBufferSizeInPages(size_t pages); |
| |
| // Returns the number of CPUs. |
| // This will match the number of tracing/per_cpu/cpuXX directories. |
| size_t virtual NumberOfCpus() const; |
| |
| // Clears the trace buffers for all CPUs. Blocks until this is done. |
| void ClearTrace(); |
| |
| // Clears the trace buffer for cpu. Blocks until this is done. |
| void ClearPerCpuTrace(size_t cpu); |
| |
| // Writes the string |str| as an event into the trace buffer. |
| bool WriteTraceMarker(const std::string& str); |
| |
| // Read tracing_on and return true if tracing_on is 1, otherwise return false. |
| bool GetTracingOn(); |
| |
| // Write 1 to tracing_on if |on| is true, otherwise write 0. |
| bool SetTracingOn(bool on); |
| |
| // Returns true if ftrace tracing is available. |
| // Ftrace tracing is available iff "/current_tracer" is "nop", indicates |
| // function tracing is not in use. Necessarily |
| // racy: another program could enable/disable tracing at any point. |
| bool IsTracingAvailable(); |
| |
| // Set the clock. |clock_name| should be one of the names returned by |
| // AvailableClocks. Setting the clock clears the buffer. |
| bool SetClock(const std::string& clock_name); |
| |
| // Get the currently set clock. |
| std::string GetClock(); |
| |
| // Get all the available clocks. |
| std::set<std::string> AvailableClocks(); |
| |
| uint32_t ReadBufferPercent(); |
| bool SetBufferPercent(uint32_t percent); |
| |
| // Get all the enabled events. |
| virtual std::vector<std::string> ReadEnabledEvents(); |
| |
| // Open the raw pipe for |cpu|. |
| virtual base::ScopedFile OpenPipeForCpu(size_t cpu); |
| |
| virtual const std::set<std::string> GetEventNamesForGroup( |
| const std::string& path) const; |
| |
| // Returns the |id| for event with the given |group| and |name|. Returns 0 if |
| // the event doesn't exist, or its /id file could not be read. Not typically |
| // needed if already parsing the format file. |
| uint32_t ReadEventId(const std::string& group, const std::string& name) const; |
| |
| std::string GetRootPath() const { return root_; } |
| |
| protected: |
| // virtual and protected for testing. |
| virtual bool WriteToFile(const std::string& path, const std::string& str); |
| virtual bool AppendToFile(const std::string& path, const std::string& str); |
| virtual bool ClearFile(const std::string& path); |
| virtual bool IsFileWriteable(const std::string& path); |
| virtual char ReadOneCharFromFile(const std::string& path); |
| virtual std::string ReadFileIntoString(const std::string& path) const; |
| |
| private: |
| // Checks the trace file is present at the given root path. |
| static bool CheckRootPath(const std::string& root); |
| |
| bool WriteNumberToFile(const std::string& path, size_t value); |
| |
| const std::string root_; |
| }; |
| |
| } // namespace perfetto |
| |
| #endif // SRC_TRACED_PROBES_FTRACE_FTRACE_PROCFS_H_ |