Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Failed to find python version from target process (py-spy 0.4.0, python 3.12) #726

Open
shyn opened this issue Nov 11, 2024 · 1 comment · May be fixed by #745
Open

Error: Failed to find python version from target process (py-spy 0.4.0, python 3.12) #726

shyn opened this issue Nov 11, 2024 · 1 comment · May be fixed by #745

Comments

@shyn
Copy link

shyn commented Nov 11, 2024

Environment:

macOS 14.5
m2

python:

/opt/homebrew/Cellar/[email protected]/3.12.7_1/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python

❯ py-spy --version
py-spy 0.4.0

@lsaint
Copy link

lsaint commented Nov 14, 2024

same here

comex added a commit to comex/py-spy that referenced this issue Feb 1, 2025
Fixes benfred#726, probably.

This could use some testing.

On some builds of Python on macOS, such as my Homebrew build of Python
3.13, the version ends up in the section `__DATA,__common` instead of
`__DATA,__bss`.  This difference appears to be caused by the use of
ThinLTO.  I'm not sure exactly why LLVM does that, but for py-spy's
purposes, it suffices to scan both sections.

Implement this by having `Binary` store a `Vec` of `(addr, size)` pairs
instead of just one `bss_addr` and `bss_size`.

While I'm at it:

- Put the pyruntime section bounds into the same `Vec` rather than
  keeping it as a separate set of fields.  This was already treated like
  another bss section.

- Change all three executable-format parsing routines so that duplicate
  sections all go into the `Vec`, instead of them having to pick one BSS
  section.

- Since we are now scanning more sections, there will be more harmless
  "didn't find anything" errors.  Therefore, differentiate the cases by
  changing the return types of `check_interpreter_addresses` and
  `Version::scan_bytes` from `Result<X, Error>` to returning
  `Result<Option<X>, Error>`. "Didn't find anything" now results in
  `Ok(None)`, which the callers silently ignore, but the callers `warn!`
  on all other errors.
comex added a commit to comex/py-spy that referenced this issue Feb 1, 2025
Fixes benfred#726, probably.

This could use some testing.

On some builds of Python on macOS, such as my Homebrew build of Python
3.13, the version ends up in the section `__DATA,__common` instead of
`__DATA,__bss`.  This difference appears to be caused by the use of
ThinLTO.  I'm not sure exactly why LLVM does that, but for py-spy's
purposes, it suffices to scan both sections.

Implement this by having `Binary` store a `Vec` of `(addr, size)` pairs
instead of just one `bss_addr` and `bss_size`.

While I'm at it:

- Put the pyruntime section bounds into the same `Vec` rather than
  keeping it as a separate set of fields.  This was already treated like
  another bss section.

- Change all three executable-format parsing routines so that duplicate
  sections all go into the `Vec`, instead of them having to pick one BSS
  section.

- Since we are now scanning more sections, there will be more harmless
  "didn't find anything" errors.  Therefore, differentiate the cases by
  changing the return type of `Version::scan_bytes` from `Result<X,
  Error>` to `Result<Option<X>, Error>`. "Didn't find anything" now
  results in `Ok(None)`, which the callers silently ignore, but the
  callers `warn!` on all other errors.

- Improve error handling of `check_interpreter_address` along similar
  lines.  It now returns an iterator of `Result`s, which leaves it to
  the caller to decide how to expose the error from each individual
  address.  The callers expose them either as `warn!` (if `_PyRuntime`
  was found and we really expect this address to be valid) or just
  `debug!` (if we're brute-forcing addresses).

  Maybe this one was overkill... In brute-force mode, it does waste time
  formatting errors that will never be shown most of the time, but in
  practice this shouldn't have noticeable impact: the number of
  addresses being brute-forced isn't _that_ large.
comex added a commit to comex/py-spy that referenced this issue Feb 1, 2025
Fixes benfred#726, probably.

This could use some testing.

On some builds of Python on macOS, such as my Homebrew build of Python
3.13, the version ends up in the section `__DATA,__common` instead of
`__DATA,__bss`.  This difference appears to be caused by the use of
ThinLTO.  I'm not sure exactly why LLVM does that, but for py-spy's
purposes, it suffices to scan both sections.

Implement this by having `Binary` store a `Vec` of `(addr, size)` pairs
instead of just one `bss_addr` and `bss_size`.

While I'm at it:

- Put the pyruntime section bounds into the same `Vec` rather than
  keeping it as a separate set of fields.  This was already treated like
  another bss section.

- Change all three executable-format parsing routines so that duplicate
  sections all go into the `Vec`, instead of them having to pick one BSS
  section.

- Since we are now scanning more sections, there will be more harmless
  "didn't find anything" errors.  Therefore, differentiate the cases by
  changing the return type of `Version::scan_bytes` from `Result<X,
  Error>` to `Result<Option<X>, Error>`. "Didn't find anything" now
  results in `Ok(None)`, which the callers silently ignore, but the
  callers `warn!` on all other errors.

- Improve error handling of `check_interpreter_address` along similar
  lines.  It now returns an iterator of `Result`s, which leaves it to
  the caller to decide how to expose the error from each individual
  address.  The callers expose them either as `warn!` (if `_PyRuntime`
  was found and we really expect this address to be valid) or just
  `debug!` (if we're brute-forcing addresses).

  Maybe this one was overkill... In brute-force mode, it does waste time
  formatting errors that will never be shown most of the time, but in
  practice this shouldn't have noticeable impact: the number of
  addresses being brute-forced isn't _that_ large.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants