1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_
#define COMPONENTS_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_
#include <stdint.h>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/process/process_handle.h"
#include "base/sequence_checker.h"
#include "base/win/sid.h"
#include "components/tracing/tracing_export.h"
namespace tracing {
// A helper that tracks active processes on the system and categorizes them,
// providing an efficient determination of a process's category given a thread
// id. An instance of this class is expected to be populated dynamically based
// on Process and Thread events sourced from the Windows system event provider
// via ETW. It provides accurate results to the extent possible, given that
// trace events may be lost.
class TRACING_EXPORT ActiveProcesses {
public:
// A process's category. Values of this type must be sequential and begin with
// zero, but are not persisted or transmitted. Values may be reordered, added,
// or removed.
enum class Category {
// A process that belongs to the tracing client.
kClient = 0,
// A process that belongs to the system.
kSystem = 1,
// Any process that doesn't meet the criteria above.
kOther = 2,
};
// Constructs an instance for a trace initiated on behalf of the process
// identified by `client_pid`. This and 1) any of its direct children of it
// with the same image filename and 2) any other program residing in the same
// directory tree will be categorized as belonging to the tracing client.
explicit ActiveProcesses(base::ProcessId client_pid);
ActiveProcesses(const ActiveProcesses&) = delete;
ActiveProcesses& operator=(const ActiveProcesses&) = delete;
~ActiveProcesses();
// Adds a process to the collection of active processes. The process is
// categorized upon addition unless the client process has yet to be added.
// If `pid` matches `client_pid`, all previously-added processes are
// categorized.
void AddProcess(uint32_t pid,
uint32_t parent_pid,
uint32_t session_id,
std::optional<base::win::Sid> sid,
std::string image_file_name,
std::wstring command_line);
// Removes a process and all of its threads from the collection.
void RemoveProcess(uint32_t pid);
// Adds a process's thread to the collection.
void AddThread(uint32_t pid, uint32_t tid, std::wstring thread_name);
// Sets the name of a thread in the collection.
void SetThreadName(uint32_t pid, uint32_t tid, std::wstring thread_name);
// Remove's a process's thread from the collection, if it is present.
void RemoveThread(uint32_t pid, uint32_t tid);
// Returns the category for the process to which the thread `tid` belongs.
// Returns kOther if `tid` is unknown.
Category GetThreadCategory(uint32_t tid) const;
// Returns a thread's name, or an empty view if not found or unset. The
// returned view may become invalidated following any other operation on this
// instance.
std::wstring_view GetThreadName(uint32_t tid) const;
// Returns a process's image file name, or an empty view if not found or
// unset. The returned view may become invalidated following any other
// operation on this instance.
std::string_view GetProcessImageFileName(uint32_t pid) const;
private:
struct Process {
Process(uint32_t pid,
uint32_t parent_pid,
uint32_t session_id,
std::optional<base::win::Sid> sid,
std::string image_file_name,
std::wstring command_line);
~Process();
uint32_t pid;
uint32_t parent_pid;
uint32_t session_id;
std::optional<base::win::Sid> sid;
std::string image_file_name;
std::wstring command_line;
Category category;
std::unordered_set<uint32_t> threads;
};
// Handles addition of the `Process` corresponding to the tracing client. All
// previously-added processes of type `kOther` are recategorized.
void OnClientAdded(Process* client);
// Handles removal of the `Process` corresponding to the tracing client. All
// previously-added processes of type `kClient` are recategorized as
// `kOther`.
void OnClientRemoved(Process* client);
// Compute and returns the category of `process`.
Category DetermineCategory(const Process& process);
// Returns the first component of `process`'s `command_line.
static base::FilePath GetProgram(const Process& process);
// The pid of the client process on behalf of which traces are collected.
const base::ProcessId client_pid_;
// The path to the application directory of which the service is a part. In
// the case of Google Chrome, this is the path to the "Application" directory
// containing chrome.exe and the version directory.
const base::FilePath application_dir_;
// True if the client appears to "belong to" the service, in the sense that it
// resides either in the same directory as the service or one directory above
// if the service is in a version directory.
bool client_in_application_ = false;
// A mapping of a process's id (pid) to its `Process` struct.
using PidProcessMap = std::unordered_map<uint32_t, Process>;
PidProcessMap processes_;
// A mapping of a thread's id (tid) to its name and corresponding process.
std::unordered_map<uint32_t, std::pair<std::wstring, raw_ptr<Process>>>
threads_;
// The `Process` struct with pid `client_pid_`, or null if the process has
// not yet been added or has been removed.
raw_ptr<Process> client_process_ = nullptr;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace tracing
#endif // COMPONENTS_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_
|