blob: 3fa22ecaa23144047c85be589a7671fe2c057543 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]32f5e9a02013-05-23 12:59:542// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Tom Sepez8726d30e2025-01-29 02:11:085#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
7#pragma allow_unsafe_libc_calls
8#endif
9
[email protected]32f5e9a02013-05-23 12:59:5410// This file contains internal routines that are called by other files in
11// base/process/.
12
danakj0a448602015-03-10 00:31:1613#ifndef BASE_PROCESS_INTERNAL_LINUX_H_
14#define BASE_PROCESS_INTERNAL_LINUX_H_
[email protected]32f5e9a02013-05-23 12:59:5415
avibeced7c2015-12-24 06:47:5916#include <stddef.h>
17#include <stdint.h>
[email protected]50b710c2013-11-13 19:18:5918#include <unistd.h>
Helmut Januschkabfa62f72024-04-04 15:18:3119
Joe Masonba145282024-03-12 20:18:1920#include <optional>
Sumaid Syed22f60eeb2021-08-26 05:16:2621#include <string>
Helmut Januschkabfa62f72024-04-04 15:18:3122#include <string_view>
Sumaid Syed22f60eeb2021-08-26 05:16:2623#include <vector>
[email protected]50b710c2013-11-13 19:18:5924
Joe Masonba145282024-03-12 20:18:1925#include "base/containers/span.h"
Eric Seckler384f9532020-08-06 09:41:5626#include "base/files/dir_reader_posix.h"
[email protected]32f5e9a02013-05-23 12:59:5427#include "base/files/file_path.h"
Eric Seckler384f9532020-08-06 09:41:5628#include "base/process/process_handle.h"
29#include "base/strings/string_number_conversions.h"
Matthew Dentonf969883422023-08-08 01:44:3430#include "base/strings/string_split.h"
Eric Seckler384f9532020-08-06 09:41:5631#include "base/threading/platform_thread.h"
[email protected]32f5e9a02013-05-23 12:59:5432
33namespace base {
[email protected]36e8fd42013-08-08 17:24:1834
35class Time;
36class TimeDelta;
37
[email protected]32f5e9a02013-05-23 12:59:5438namespace internal {
39
40// "/proc"
41extern const char kProcDir[];
42
43// "stat"
44extern const char kStatFile[];
45
46// Returns a FilePath to "/proc/pid".
Joel Fernandes9a9d7572023-09-22 20:46:0547BASE_EXPORT base::FilePath GetProcPidDir(pid_t pid);
[email protected]32f5e9a02013-05-23 12:59:5448
Eric Seckler9db21392020-06-12 08:48:1949// Reads a file from /proc into a string. This is allowed on any thread as
50// reading from /proc does not hit the disk. Returns true if the file can be
51// read and is non-empty.
52bool ReadProcFile(const FilePath& file, std::string* buffer);
53
[email protected]32f5e9a02013-05-23 12:59:5454// Take a /proc directory entry named |d_name|, and if it is the directory for
55// a process, convert it to a pid_t.
56// Returns 0 on failure.
57// e.g. /proc/self/ will return 0, whereas /proc/1234 will return 1234.
Jan Keitel26cbcde52024-08-12 07:02:0058pid_t ProcDirSlotToPid(std::string_view d_name);
[email protected]32f5e9a02013-05-23 12:59:5459
Joe Mason484bfa52025-05-16 21:14:4060// Read `filename` in /proc/<pid>/, split the entries into key/value pairs, and
61// trim the key and value. On success, writes the file contents into `buffer`
62// and returns the trimmed key/value pairs as views into that buffer. On
63// failure, returns nullopt (the buffer contents may or may not be changed).
64std::optional<StringViewPairs> ReadProcFileToTrimmedStringPairs(
65 pid_t pid,
66 std::string_view filename,
67 std::string* buffer);
Matthew Dentonf969883422023-08-08 01:44:3468
69// Read /proc/<pid>/status and return the value for |field|, or 0 on failure.
70// Only works for fields in the form of "Field: value kB".
Helmut Januschkabfa62f72024-04-04 15:18:3171size_t ReadProcStatusAndGetKbFieldAsSizeT(pid_t pid, std::string_view field);
Matthew Dentonf969883422023-08-08 01:44:3472
73// Read /proc/<pid>/status and look for |field|. On success, return true and
74// write the value for |field| into |result|.
75// Only works for fields in the form of "field : uint_value"
76bool ReadProcStatusAndGetFieldAsUint64(pid_t pid,
Helmut Januschkabfa62f72024-04-04 15:18:3177 std::string_view field,
Matthew Dentonf969883422023-08-08 01:44:3478 uint64_t* result);
79
[email protected]32f5e9a02013-05-23 12:59:5480// Reads /proc/<pid>/stat into |buffer|. Returns true if the file can be read
81// and is non-empty.
82bool ReadProcStats(pid_t pid, std::string* buffer);
83
Joe Mason484bfa52025-05-16 21:14:4084// Takes `stats_data` and populates `proc_stats` with the values split by
85// spaces, as views into `stats_data`, taking into account the 2nd field may
86// itself contain spaces. Returns true if successful.
87bool ParseProcStats(std::string_view stats_data,
88 std::vector<std::string_view>* proc_stats);
[email protected]32f5e9a02013-05-23 12:59:5489
90// Fields from /proc/<pid>/stat, 0-based. See man 5 proc.
91// If the ordering ever changes, carefully review functions that use these
92// values.
93enum ProcStatsFields {
Benoit Lize448ee882017-08-31 13:32:1294 VM_COMM = 1, // Filename of executable, without parentheses.
95 VM_STATE = 2, // Letter indicating the state of the process.
96 VM_PPID = 3, // PID of the parent.
97 VM_PGRP = 4, // Process group id.
98 VM_MINFLT = 9, // Minor page fault count excluding children.
99 VM_MAJFLT = 11, // Major page fault count excluding children.
100 VM_UTIME = 13, // Time scheduled in user mode in clock ticks.
101 VM_STIME = 14, // Time scheduled in kernel mode in clock ticks.
102 VM_NUMTHREADS = 19, // Number of threads.
103 VM_STARTTIME = 21, // The time the process started in clock ticks.
104 VM_VSIZE = 22, // Virtual memory size in bytes.
105 VM_RSS = 23, // Resident Set Size in pages.
[email protected]32f5e9a02013-05-23 12:59:54106};
107
108// Reads the |field_num|th field from |proc_stats|. Returns 0 on failure.
109// This version does not handle the first 3 values, since the first value is
110// simply |pid|, and the next two values are strings.
Joe Mason484bfa52025-05-16 21:14:40111int64_t GetProcStatsFieldAsInt64(base::span<std::string_view> proc_stats,
avibeced7c2015-12-24 06:47:59112 ProcStatsFields field_num);
[email protected]32f5e9a02013-05-23 12:59:54113
Joe Masonba145282024-03-12 20:18:19114// Reads the `field_num`th field from `proc_stats`. Asserts that `field_num` is
115// a valid index into `proc_stats`. Returns nullopt if the field doesn't contain
116// a valid integer.
117std::optional<int64_t> GetProcStatsFieldAsOptionalInt64(
Joe Mason484bfa52025-05-16 21:14:40118 base::span<std::string_view> proc_stats,
Joe Masonba145282024-03-12 20:18:19119 ProcStatsFields field_num);
120
[email protected]a98084792014-01-09 01:39:24121// Same as GetProcStatsFieldAsInt64(), but for size_t values.
Joe Mason484bfa52025-05-16 21:14:40122size_t GetProcStatsFieldAsSizeT(base::span<std::string_view> proc_stats,
[email protected]32f5e9a02013-05-23 12:59:54123 ProcStatsFields field_num);
124
dcastagna4c25edc2017-02-23 19:35:51125// Convenience wrappers around GetProcStatsFieldAsInt64(), ParseProcStats() and
[email protected]a98084792014-01-09 01:39:24126// ReadProcStats(). See GetProcStatsFieldAsInt64() for details.
dcastagna4c25edc2017-02-23 19:35:51127int64_t ReadStatsFilendGetFieldAsInt64(const FilePath& stat_file,
128 ProcStatsFields field_num);
avibeced7c2015-12-24 06:47:59129int64_t ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num);
dcastagna4c25edc2017-02-23 19:35:51130int64_t ReadProcSelfStatsAndGetFieldAsInt64(ProcStatsFields field_num);
[email protected]32f5e9a02013-05-23 12:59:54131
[email protected]a98084792014-01-09 01:39:24132// Same as ReadProcStatsAndGetFieldAsInt64() but for size_t values.
Peter Kasting134ef9af2024-12-28 02:30:09133size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, ProcStatsFields field_num);
[email protected]32f5e9a02013-05-23 12:59:54134
[email protected]36e8fd42013-08-08 17:24:18135// Returns the time that the OS started. Clock ticks are relative to this.
136Time GetBootTime();
137
thomasandersonfc4688ab2016-09-10 01:19:43138// Returns the amount of time spent in user space since boot across all CPUs.
139TimeDelta GetUserCpuTimeSinceBoot();
140
[email protected]36e8fd42013-08-08 17:24:18141// Converts Linux clock ticks to a wall time delta.
Peter Kastingaca170a2022-06-30 17:18:48142TimeDelta ClockTicksToTimeDelta(int64_t clock_ticks);
[email protected]36e8fd42013-08-08 17:24:18143
Eric Seckler384f9532020-08-06 09:41:56144// Executes the lambda for every task in the process's /proc/<pid>/task
145// directory. The thread id and file path of the task directory are provided as
146// arguments to the lambda.
147template <typename Lambda>
148void ForEachProcessTask(base::ProcessHandle process, Lambda&& lambda) {
149 // Iterate through the different threads tracked in /proc/<pid>/task.
150 FilePath fd_path = GetProcPidDir(process).Append("task");
151
152 DirReaderPosix dir_reader(fd_path.value().c_str());
Peter Kasting134ef9af2024-12-28 02:30:09153 if (!dir_reader.IsValid()) {
Eric Seckler384f9532020-08-06 09:41:56154 return;
Peter Kasting134ef9af2024-12-28 02:30:09155 }
Eric Seckler384f9532020-08-06 09:41:56156
157 for (; dir_reader.Next();) {
158 const char* tid_str = dir_reader.name();
Peter Kasting134ef9af2024-12-28 02:30:09159 if (strcmp(tid_str, ".") == 0 || strcmp(tid_str, "..") == 0) {
Eric Seckler384f9532020-08-06 09:41:56160 continue;
Peter Kasting134ef9af2024-12-28 02:30:09161 }
Eric Seckler384f9532020-08-06 09:41:56162
Leszek Swirskib3fb42322025-02-06 12:16:57163 PlatformThreadId::UnderlyingType tid_value;
164 if (!StringToInt(tid_str, &tid_value)) {
Eric Seckler384f9532020-08-06 09:41:56165 continue;
Peter Kasting134ef9af2024-12-28 02:30:09166 }
Leszek Swirskib3fb42322025-02-06 12:16:57167 PlatformThreadId tid(tid_value);
Eric Seckler384f9532020-08-06 09:41:56168
169 FilePath task_path = fd_path.Append(tid_str);
170 lambda(tid, task_path);
171 }
172}
173
[email protected]32f5e9a02013-05-23 12:59:54174} // namespace internal
175} // namespace base
176
danakj0a448602015-03-10 00:31:16177#endif // BASE_PROCESS_INTERNAL_LINUX_H_