Skip to content

Commit b4900b1

Browse files
committed
Enable feature unwind by default
Enable feature `unwind` by default, user can disable it by using: `cargo build --no-default-features` Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
1 parent 0ca763a commit b4900b1

File tree

8 files changed

+35
-29
lines changed

8 files changed

+35
-29
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[features]
2-
unwind = []
3-
41
[package]
52
name = "py-spy"
63
version = "0.4.0"
@@ -49,3 +46,7 @@ termios = "0.3.3"
4946

5047
[target.'cfg(windows)'.dependencies]
5148
winapi = {version = "0.3", features = ["errhandlingapi", "winbase", "consoleapi", "wincon", "handleapi", "timeapi", "processenv" ]}
49+
50+
[features]
51+
default = ["unwind"]
52+
unwind = ["remoteprocess/unwind"]

src/config.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,11 @@ impl Config {
166166
.help("Collect stack traces from native extensions written in Cython, C or C++");
167167

168168
// Only show `--native` on platforms where it's supported
169-
if !cfg!(feature = "unwind") {
169+
if !cfg!(all(
170+
feature = "unwind",
171+
target_os = "linux",
172+
target_arch = "x86_64"
173+
)) {
170174
native = native.hide(true);
171175
}
172176

@@ -362,7 +366,7 @@ impl Config {
362366
let (subcommand, matches) = matches.subcommand().unwrap();
363367

364368
// Check if `--native` was used on an unsupported platform
365-
if !cfg!(feature = "unwind") && matches.contains_id("native") {
369+
if native.is_hide_set() && matches.contains_id("native") {
366370
eprintln!(
367371
"Collecting stack traces from native extensions (`--native`) is not supported on your platform."
368372
);
@@ -437,9 +441,7 @@ impl Config {
437441
.value_of("pid")
438442
.map(|p| p.parse().expect("invalid pid"));
439443
config.full_filenames = matches.occurrences_of("full_filenames") > 0;
440-
if cfg!(feature = "unwind") {
441-
config.native = matches.occurrences_of("native") > 0;
442-
}
444+
config.native = matches.occurrences_of("native") > 0;
443445

444446
config.capture_output = config.command != "record" || matches.occurrences_of("capture") > 0;
445447
if !config.capture_output {

src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ pub mod binary_parser;
3333
pub mod config;
3434
#[cfg(target_os = "linux")]
3535
pub mod coredump;
36-
#[cfg(feature = "unwind")]
37-
mod cython;
3836
pub mod dump;
39-
#[cfg(feature = "unwind")]
37+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
4038
mod native_stack_trace;
4139
mod python_bindings;
4240
mod python_data_access;

src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ mod config;
99
mod console_viewer;
1010
#[cfg(target_os = "linux")]
1111
mod coredump;
12-
#[cfg(feature = "unwind")]
13-
mod cython;
1412
mod dump;
1513
mod flamegraph;
16-
#[cfg(feature = "unwind")]
14+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
1715
mod native_stack_trace;
1816
mod python_bindings;
1917
mod python_data_access;

src/native_stack_trace.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use lru::LruCache;
88
use remoteprocess::{self, Pid};
99

1010
use crate::binary_parser::BinaryInfo;
11-
use crate::cython;
1211
use crate::stack_trace::Frame;
1312
use crate::utils::resolve_filename;
1413

14+
#[path = "cython.rs"]
15+
mod cython;
16+
1517
pub struct NativeStack {
1618
should_reload: bool,
1719
python: Option<BinaryInfo>,

src/python_spy.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
use std::collections::HashMap;
2-
#[cfg(all(target_os = "linux", feature = "unwind"))]
3-
use std::collections::HashSet;
4-
#[cfg(all(target_os = "linux", feature = "unwind"))]
5-
use std::iter::FromIterator;
62
use std::path::Path;
73

84
use anyhow::{Context, Error, Result};
95
use remoteprocess::{Pid, Process, ProcessMemory, Tid};
106

117
use crate::config::{Config, LockingStrategy};
12-
#[cfg(feature = "unwind")]
8+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
139
use crate::native_stack_trace::NativeStack;
1410
use crate::python_bindings::{
1511
v2_7_15, v3_10_0, v3_11_0, v3_12_0, v3_13_0, v3_3_7, v3_5_5, v3_6_6, v3_7_0, v3_8_0, v3_9_5,
@@ -31,7 +27,7 @@ pub struct PythonSpy {
3127
pub interpreter_address: usize,
3228
pub threadstate_address: usize,
3329
pub config: Config,
34-
#[cfg(feature = "unwind")]
30+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
3531
pub native: Option<NativeStack>,
3632
pub short_filenames: HashMap<String, Option<String>>,
3733
pub python_thread_ids: HashMap<u64, Tid>,
@@ -65,7 +61,7 @@ impl PythonSpy {
6561
let threadstate_address =
6662
get_threadstate_address(interpreter_address, &python_info, &version, config)?;
6763

68-
#[cfg(feature = "unwind")]
64+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
6965
let native = if config.native {
7066
Some(NativeStack::new(
7167
pid,
@@ -82,7 +78,7 @@ impl PythonSpy {
8278
version,
8379
interpreter_address,
8480
threadstate_address,
85-
#[cfg(feature = "unwind")]
81+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
8682
native,
8783
#[cfg(target_os = "linux")]
8884
dockerized: python_info.dockerized,
@@ -295,7 +291,7 @@ impl PythonSpy {
295291
}
296292

297293
// Merge in the native stack frames if necessary
298-
#[cfg(feature = "unwind")]
294+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
299295
{
300296
if self.config.native {
301297
if let Some(native) = self.native.as_mut() {
@@ -393,7 +389,10 @@ impl PythonSpy {
393389
Ok(None)
394390
}
395391

396-
#[cfg(all(target_os = "linux", not(feature = "unwind")))]
392+
#[cfg(all(
393+
target_os = "linux",
394+
not(all(feature = "unwind", target_arch = "x86_64"))
395+
))]
397396
fn _get_os_thread_id<I: InterpreterState>(
398397
&mut self,
399398
_python_thread_id: u64,
@@ -402,12 +401,14 @@ impl PythonSpy {
402401
Ok(None)
403402
}
404403

405-
#[cfg(all(target_os = "linux", feature = "unwind"))]
404+
#[cfg(all(target_os = "linux", feature = "unwind", target_arch = "x86_64"))]
406405
fn _get_os_thread_id<I: InterpreterState>(
407406
&mut self,
408407
python_thread_id: u64,
409408
interp: &I,
410409
) -> Result<Option<Tid>, Error> {
410+
use std::collections::HashSet;
411+
411412
// in nonblocking mode, we can't get the threadid reliably (method here requires reading the RBX
412413
// register which requires a ptrace attach). fallback to heuristic thread activity here
413414
if self.config.blocking == LockingStrategy::NonBlocking {
@@ -453,6 +454,8 @@ impl PythonSpy {
453454
Ok(pthread_id) => {
454455
if pthread_id != 0 {
455456
self.python_thread_ids.insert(pthread_id, threadid);
457+
} else if self.config.native {
458+
panic!("Native stack traces not supported on this platform");
456459
}
457460
}
458461
Err(e) => {
@@ -487,12 +490,12 @@ impl PythonSpy {
487490
Ok(None)
488491
}
489492

490-
#[cfg(all(target_os = "linux", feature = "unwind"))]
493+
#[cfg(all(target_os = "linux", feature = "unwind", target_arch = "x86_64"))]
491494
pub fn _get_pthread_id(
492495
&self,
493496
unwinder: &remoteprocess::Unwinder,
494497
thread: &remoteprocess::Thread,
495-
threadids: &HashSet<u64>,
498+
threadids: &std::collections::HashSet<u64>,
496499
) -> Result<u64, Error> {
497500
let mut pthread_id = 0;
498501

src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use num_traits::{CheckedAdd, Zero};
22
use std::ops::Add;
33

4-
#[cfg(feature = "unwind")]
4+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
55
pub fn resolve_filename(filename: &str, modulename: &str) -> Option<String> {
66
// check the filename first, if it exists use it
77
use std::path::Path;

tests/integration_test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ fn test_busy_loop() {
6262
assert!(traces[0].active);
6363
}
6464

65+
// TODO: fix https://github.com/benfred/py-spy/issues/701
66+
#[ignore]
6567
#[cfg(feature = "unwind")]
6668
#[test]
6769
fn test_thread_reuse() {

0 commit comments

Comments
 (0)