ApplePowermetrics._setup_cli silently succeeds on Intel Macs
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.9k
- Forks
- 323
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 12
Description
Problem
ApplePowermetrics._setup_cli() is meant to validate that powermetrics can be used, but on an Intel Mac it falls through all of its branches and returns without either assigning self._cli or raising. As a result ApplePowermetrics() succeeds on non-Apple-Silicon hardware, is_powermetrics_available() returns True whenever a passwordless sudo rule exists, and ResourceTracker ends up registering an AppleSiliconChip for a machine that has no Apple Silicon chip. The measurements it then reports come from a code path that was never intended for that hardware.
The same function also crashes with an unexpected AttributeError when detect_cpu_model() returns None, which the broad except Exception in is_powermetrics_available() turns into a misleading "Not using PowerMetrics" debug line, hiding a genuine cpuinfo failure.
Reproduction
from unittest import mock
from codecarbon.core.powermetrics import ApplePowermetrics
with mock.patch("codecarbon.core.powermetrics.sys.platform", "darwin"), \
mock.patch("codecarbon.core.powermetrics.detect_cpu_model",
return_value="Intel(R) Core(TM) i7-9750H"):
pm = ApplePowermetrics() # succeeds, should not
pm._cli # AttributeError
Root cause
codecarbon/core/powermetrics.py:117—_setup_cli()has no terminalelsefor the "darwin but not Apple" case, so it returns silently.codecarbon/core/powermetrics.py:122—cpu_model.startswith(...)on theOptional[str]returned bycodecarbon/core/util.py:77.codecarbon/core/powermetrics.py:141—_log_values()hardcodes"powermetrics"in the argv instead of usingself._cli, which is why the missing assignment never surfaced as an error; the validation is effectively dead for its only caller.
Two smaller defects in the same argv:
codecarbon/core/powermetrics.py:146— a stray""is passed topowermetricsas a positional argument. Harmless on current macOS, but it is unintentional and a stricter parser would reject it.codecarbon/core/powermetrics.py:156—subprocess.callhas no timeout, so a hungpowermetricsblocks the measurement thread indefinitely.
Expected vs actual
Expected: on a Mac that is not Apple Silicon, _setup_cli() raises SystemError, is_powermetrics_available() returns False, and ResourceTracker falls through to Intel Power Gadget or the CPU-load fallback as _try_platform_cpu_backend (codecarbon/core/resource_tracker.py:225) intends.
Actual: ApplePowermetrics() is constructed successfully, powermetrics is selected, and an AppleSiliconChip is registered on Intel hardware. With detect_cpu_model() returning None, an AttributeError is swallowed and reported as powermetrics simply being unavailable.
Note for the changelog: machines that were accidentally using powermetrics on Intel Macs will change tracking method after this fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codecarbon/core/powermetrics.py at _setup_cli(), is_powermetrics_available(), and _log_values(), then inspect detect_cpu_model() in codecarbon/core/util.py and _try_platform_cpu_backend in codecarbon/core/resource_tracker.py. Reproduce the Intel and None CPU-model cases from the issue, then verify that the expected fallback behavior and powermetrics invocation are covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, python
- Domain
- backend, operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100