Skip to content

Commit 2a679f3

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 7c33089 commit 2a679f3

File tree

9 files changed

+39
-31
lines changed

9 files changed

+39
-31
lines changed

Cargo.toml

Lines changed: 5 additions & 4 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.3.14"
@@ -37,7 +34,7 @@ serde_derive = "1.0"
3734
serde_json = "1.0"
3835
rand = "0.8"
3936
rand_distr = "0.4"
40-
remoteprocess = {version="0.4.12", features=["unwind"]}
37+
remoteprocess = "0.4.12"
4138
chrono = "0.4.26"
4239

4340
[dev-dependencies]
@@ -48,3 +45,7 @@ termios = "0.3.3"
4845

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

src/binary_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct BinaryInfo {
1717
}
1818

1919
impl BinaryInfo {
20-
#[cfg(feature = "unwind")]
20+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
2121
pub fn contains(&self, addr: u64) -> bool {
2222
addr >= self.addr && addr < (self.addr + self.size)
2323
}

src/config.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl Config {
160160
.help("PID of a running python program to spy on")
161161
.takes_value(true);
162162

163-
#[cfg(feature = "unwind")]
163+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
164164
let native = Arg::new("native")
165165
.short('n')
166166
.long("native")
@@ -328,11 +328,11 @@ impl Config {
328328
);
329329

330330
// add native unwinding if appropriate
331-
#[cfg(feature = "unwind")]
331+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
332332
let record = record.arg(native.clone());
333-
#[cfg(feature = "unwind")]
333+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
334334
let top = top.arg(native.clone());
335-
#[cfg(feature = "unwind")]
335+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
336336
let dump = dump.arg(native.clone());
337337

338338
// Nonblocking isn't an option for freebsd, remove
@@ -429,7 +429,11 @@ impl Config {
429429
.value_of("pid")
430430
.map(|p| p.parse().expect("invalid pid"));
431431
config.full_filenames = matches.occurrences_of("full_filenames") > 0;
432-
if cfg!(feature = "unwind") {
432+
if cfg!(all(
433+
feature = "unwind",
434+
target_os = "linux",
435+
target_arch = "x86_64"
436+
)) {
433437
config.native = matches.occurrences_of("native") > 0;
434438
}
435439

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_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>,
@@ -64,7 +60,7 @@ impl PythonSpy {
6460
// lets us figure out which thread has the GIL
6561
let threadstate_address = get_threadstate_address(&python_info, &version, config)?;
6662

67-
#[cfg(feature = "unwind")]
63+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
6864
let native = if config.native {
6965
Some(NativeStack::new(
7066
pid,
@@ -81,7 +77,7 @@ impl PythonSpy {
8177
version,
8278
interpreter_address,
8379
threadstate_address,
84-
#[cfg(feature = "unwind")]
80+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
8581
native,
8682
#[cfg(target_os = "linux")]
8783
dockerized: python_info.dockerized,
@@ -288,7 +284,7 @@ impl PythonSpy {
288284
}
289285

290286
// Merge in the native stack frames if necessary
291-
#[cfg(feature = "unwind")]
287+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
292288
{
293289
if self.config.native {
294290
if let Some(native) = self.native.as_mut() {
@@ -386,7 +382,10 @@ impl PythonSpy {
386382
Ok(None)
387383
}
388384

389-
#[cfg(all(target_os = "linux", not(feature = "unwind")))]
385+
#[cfg(all(
386+
target_os = "linux",
387+
not(all(feature = "unwind", target_arch = "x86_64"))
388+
))]
390389
fn _get_os_thread_id<I: InterpreterState>(
391390
&mut self,
392391
_python_thread_id: u64,
@@ -395,12 +394,14 @@ impl PythonSpy {
395394
Ok(None)
396395
}
397396

398-
#[cfg(all(target_os = "linux", feature = "unwind"))]
397+
#[cfg(all(target_os = "linux", feature = "unwind", target_arch = "x86_64"))]
399398
fn _get_os_thread_id<I: InterpreterState>(
400399
&mut self,
401400
python_thread_id: u64,
402401
interp: &I,
403402
) -> Result<Option<Tid>, Error> {
403+
use std::collections::HashSet;
404+
404405
// in nonblocking mode, we can't get the threadid reliably (method here requires reading the RBX
405406
// register which requires a ptrace attach). fallback to heuristic thread activity here
406407
if self.config.blocking == LockingStrategy::NonBlocking {
@@ -446,6 +447,8 @@ impl PythonSpy {
446447
Ok(pthread_id) => {
447448
if pthread_id != 0 {
448449
self.python_thread_ids.insert(pthread_id, threadid);
450+
} else if self.config.native {
451+
panic!("Native stack traces not supported on this platform");
449452
}
450453
}
451454
Err(e) => {
@@ -480,12 +483,12 @@ impl PythonSpy {
480483
Ok(None)
481484
}
482485

483-
#[cfg(all(target_os = "linux", feature = "unwind"))]
486+
#[cfg(all(target_os = "linux", feature = "unwind", target_arch = "x86_64"))]
484487
pub fn _get_pthread_id(
485488
&self,
486489
unwinder: &remoteprocess::Unwinder,
487490
thread: &remoteprocess::Thread,
488-
threadids: &HashSet<u64>,
491+
threadids: &std::collections::HashSet<u64>,
489492
) -> Result<u64, Error> {
490493
let mut pthread_id = 0;
491494

src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cfg(feature = "unwind")]
1+
#[cfg(all(feature = "unwind", target_os = "linux", target_arch = "x86_64"))]
22
pub fn resolve_filename(filename: &str, modulename: &str) -> Option<String> {
33
// check the filename first, if it exists use it
44
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)