Repository navigation
Conversation
4f77516 to
44986d5
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
4 open findings
statis no longer zero-initialized on macOS (the previous implementation did `memset(&stat, 0,… · New On failure, the function now returnsfalsewithout clearingm, whereas the previous code path… · New The return value assumesbytesis always a clean multiple ofsizeof(proc_fdinfo). If… · New This log line prints only the numerickern_return_t, which is difficult to interpret… · New
What changed in this PR
This PR replaces macOS process-metrics collection that relied on shelling out to ps/lsof with native macOS APIs to improve reliability under sandbox/permission restrictions and to expose additional metrics.
Changes:
- Reworked macOS
read_proc_statusto usegetpid/getppid/getpgrp/getsid,getpriority,proc_pidinfo, andgetrusage. - Reworked macOS
read_proc_memoryto usetask_info(MACH_TASK_BASIC_INFO)for RSS/VSS. - Implemented macOS FD counting via
proc_pidinfo(PROC_PIDLISTFDS)and adjusted FD scan-limit condition.
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const pid_t pid = getpid(); | ||
| stat.pid = pid; | ||
| stat.ppid = getppid(); | ||
| stat.pgrp = getpgrp(); | ||
| const pid_t session = getsid(0); | ||
| stat.session = session >= 0 ? session : 0; | ||
| errno = 0; | ||
| const int nice = getpriority(PRIO_PROCESS, 0); | ||
| if (errno == 0) | ||
| stat.nice = nice; | ||
| struct proc_bsdinfo bsd = {}; |
There was a problem hiding this comment.
stat is already value-initialized at the beginning of read_proc_status() via stat = ProcStat().
| mach_task_basic_info_data_t info = {}; | ||
| mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; | ||
| const kern_return_t result = task_info( | ||
| mach_task_self(), MACH_TASK_BASIC_INFO, | ||
| reinterpret_cast<task_info_t>(&info), &count); | ||
| if (result != KERN_SUCCESS) { | ||
| LOG_ONCE(WARNING) << "Cannot read own task memory, Mach error=" << result; | ||
| return false; | ||
| } |
There was a problem hiding this comment.
m has been zero-initialized at the beginning of m = ProcMemory(), it won’t be partially assigned when return false here.
| return std::min(count, limit); | ||
| */ | ||
| return 0; | ||
| return bytes / sizeof(proc_fdinfo); |
There was a problem hiding this comment.
Added validation that the returned byte count is a multiple of sizeof(proc_fdinfo) and does not exceed the buffer size. Unexpected lengths are logged and return -1, allowing the reader to retain the last valid count.
Since the buffer holds exactly limit entries, a validated result cannot exceed limit, so an additional clamp is unnecessary.
| mach_task_self(), MACH_TASK_BASIC_INFO, | ||
| reinterpret_cast<task_info_t>(&info), &count); | ||
| if (result != KERN_SUCCESS) { | ||
| LOG_ONCE(WARNING) << "Cannot read own task memory, Mach error=" << result; |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
6 open findings
This lambda does not captureticks_per_second, so it won’t compile (use of an enclosing-scope… · Newstatis no longer zero-initialized on macOS (the previous implementation did `memset(&stat, 0,… This allocates astd::vectoron every call, which can add avoidable CPU/memory churn if FD… · New The return value assumesbytesis always a clean multiple ofsizeof(proc_fdinfo). If… On failure, the function now returnsfalsewithout clearingm, whereas the previous code path… This log line prints only the numerickern_return_t, which is difficult to interpret…
🧠 Review effort: Lite
| static const long ticks_per_second = sysconf(_SC_CLK_TCK); | ||
| const auto to_ticks = [](const timeval &time) -> unsigned long { | ||
| if (ticks_per_second <= 0) { | ||
| return 0; | ||
| } | ||
| return static_cast<uint64_t>(time.tv_sec) * ticks_per_second + | ||
| static_cast<uint64_t>(time.tv_usec) * ticks_per_second / 1000000; | ||
| }; |
There was a problem hiding this comment.
ticks_per_second is a local static variable which caches the constant tick rate, avoiding repeated sysconf() calls, so the lambda can access it without capturing it.
There was a problem hiding this comment.
Changed to a thread_local std::vector to reuse the allocation while keeping each thread’s buffer separate.




What problem does this PR solve?
Issue Number: resolve
Problem Summary:
psandlsofmay fail due to permission restrictions in MacOS sandboxed applications.process_faults_minor_second,process_faults_minor_second,process_faults_major.What is changed and the side effects?
Changed:
This change uses native macOS APIs to collect these metrics:
Side effects:
Performance effects:
Breaking backward compatibility:
Check List: