blob: 2a0593f75b196326f2547da1cbef6a14e95845ca [file] [log] [blame]
/*
* 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_