File: active_processes_win.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (157 lines) | stat: -rw-r--r-- 6,019 bytes parent folder | download | duplicates (5)
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_