diff --git a/.travis.yml b/.travis.yml index 045105de..2771124f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -84,7 +84,7 @@ notifications: addons: apt: packages: - - python + - python3 homebrew: packages: - python diff --git a/Cargo.lock b/Cargo.lock index 304b18ea..f30de413 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,28 +90,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bindgen" -version = "0.49.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "bitflags" version = "1.1.0" @@ -136,29 +114,11 @@ name = "cc" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "cexpr" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cfg-if" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "clang-sys" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clap" version = "2.33.0" @@ -328,14 +288,6 @@ name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "getrandom" version = "0.1.7" @@ -470,15 +422,6 @@ name = "libc" version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "libloading" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "libproc" version = "0.3.2" @@ -601,15 +544,6 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-format" version = "0.4.0" @@ -676,11 +610,6 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "plain" version = "0.2.3" @@ -937,7 +866,6 @@ version = "0.1.0" dependencies = [ "addr2line 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "benfred-read-process-memory 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bindgen 0.49.2 (registry+https://github.com/rust-lang/crates.io-index)", "gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "goblin 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1050,11 +978,6 @@ dependencies = [ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "shlex" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "smallvec" version = "0.6.10" @@ -1207,25 +1130,11 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "which" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "winapi" version = "0.2.8" @@ -1283,14 +1192,11 @@ dependencies = [ "checksum backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)" = "b5164d292487f037ece34ec0de2fcede2faa162f085dd96d2385ab81b12765ba" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum benfred-read-process-memory 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3bf2e237e12009727c3b0cc39eb34f6b29dbc2957f5d643f34ade1e5a7016c9" -"checksum bindgen 0.49.2 (registry+https://github.com/rust-lang/crates.io-index)" = "846a1fba6535362a01487ef6b10f0275faa12e5c5d835c5c1c627aabc46ccbd6" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46" -"checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -1309,7 +1215,6 @@ dependencies = [ "checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8e190892c840661957ba9f32dacfb3eb405e657f9f9f60485605f0bb37d6f8" "checksum gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "162d18ae5f2e3b90a993d202f1ba17a5633c2484426f8bcae201f86194bacd00" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" @@ -1326,7 +1231,6 @@ dependencies = [ "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" -"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libproc 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58d23e79d5a9fc3f86a75bcd31a5418f27104518aca33615802b0373380beab4" "checksum libproc 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfacafc8e193a2090dd8716eca0fd2b8116801b692648441c321a88600c96f2" "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" @@ -1342,7 +1246,6 @@ dependencies = [ "checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum num-format 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee" @@ -1350,7 +1253,6 @@ dependencies = [ "checksum parity-wasm 0.38.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d7e522a7f994cc4ae32970b1ce0d99ecf91b8e1df080517a26faa6d2e2ee62" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" @@ -1390,7 +1292,6 @@ dependencies = [ "checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113" "checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" -"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum str_stack 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" @@ -1412,9 +1313,7 @@ dependencies = [ "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/examples/native_stress_test.rs b/examples/native_stress_test.rs deleted file mode 100644 index a8289211..00000000 --- a/examples/native_stress_test.rs +++ /dev/null @@ -1,60 +0,0 @@ -// This example loops over native stack traces until it fails to get one for any reason -extern crate remoteprocess; -extern crate env_logger; -#[macro_use] -extern crate log; -extern crate failure; -extern crate py_spy; - -fn native_stress_test(pid: remoteprocess::Pid) -> Result<(), failure::Error> { - - let config = py_spy::Config{native: true, ..Default::default() }; - let mut spy = py_spy::PythonSpy::retry_new(pid, &config, 3)?; - - - let mut success = 0; - let mut failed = 0; - loop { - match spy.get_stack_traces() { - Ok(_) => { - success += 1; - if success % 1000 == 0 { - info!("Success {} fail {}", success, failed) - } - }, - Err(e) => { - error!("Failed to get stack traces: {:#?}", e); - for (_i, suberror) in e.iter_chain().enumerate() { - eprintln!("Reason: {:?}", suberror); - } - - failed += 1; - info!("Success {} fail {}", success, failed); - } - } - } -} - - -#[cfg(unwind)] -fn main() { - env_logger::init(); - - let args: Vec = std::env::args().collect(); - - let pid = if args.len() > 1 { - args[1].parse::().expect("invalid pid") - } else { - error!("must specify a pid!"); - return; - }; - - if let Err(e) = native_stress_test(pid) { - println!("Failed to get backtrace {:?}", e); - } -} - -#[cfg(not(unwind))] -fn main() { - panic!("unwind not supported!"); -} diff --git a/remoteprocess/Cargo.toml b/remoteprocess/Cargo.toml index 090cdda3..16fc4874 100644 --- a/remoteprocess/Cargo.toml +++ b/remoteprocess/Cargo.toml @@ -33,6 +33,3 @@ winapi = {version = "0.3", features = ["winbase", "consoleapi", "wincon", "handl [dev-dependencies] env_logger = "0.6.1" - -[build-dependencies] -bindgen = "0.49.0" diff --git a/tests/integration_test.py b/tests/integration_test.py deleted file mode 100644 index 39cf3f86..00000000 --- a/tests/integration_test.py +++ /dev/null @@ -1,91 +0,0 @@ -import os -import re -import subprocess -import sys -import time -import unittest -from collections import namedtuple - -Frame = namedtuple("Frame", ("function", "file", "line")) -Thread = namedtuple("Thread", ("id", "status")) - - -class IntegrationTest(unittest.TestCase): - def _profile_python_file(self, filename): - # Run the python command in a subprocess - python_process = subprocess.Popen( - [sys.executable, os.path.join("scripts", filename)] - ) - try: - # hack: give it some time to get running - time.sleep(0.2) - - # Run py-spy on the pid of the process we just created - # TODO: get built py-spy here (rather than globally installed) - output = subprocess.check_output( - ["py-spy", "--pid", str(python_process.pid), "--dump"] - ) - - if sys.version_info[0] >= 3: - output = output.decode("utf8") - - traces = [] - for thread in output.split("\nThread")[1:]: - lines = thread.split("\n") - traces.append( - (parse_thread(lines[0]), [parse_frame(l) for l in lines[1:] if l]) - ) - return traces - - finally: - python_process.kill() - python_process.wait() - - def test_long_sleep(self): - traces = self._profile_python_file("longsleep.py") - self.assertEqual(len(traces), 1) - - thread, frames = traces[0] - self.assertEqual( - frames, - [ - Frame(function="longsleep", file="longsleep.py", line=5), - Frame(function="", file="longsleep.py", line=9), - ], - ) - - # should be sleeping, not holding the gil - self.assertTrue("gil" not in thread.status) - - # should be marked as idle - self.assertTrue("idle" in thread.status) - - def test_busyloop(self): - traces = self._profile_python_file("busyloop.py") - self.assertEqual(len(traces), 1) - thread, frames = traces[0] - - self.assertTrue("gil" in thread.status) - self.assertTrue("active" in thread.status) - - -def parse_frame(frame_line): - matches = re.match( - r"\s+(?P\S+) .(?P\S+):(?P\d+).", frame_line - ) - if not matches: - return None - frame = matches.groupdict() - frame["line"] = int(frame["line"]) - return Frame(**frame) - - -def parse_thread(thread_line): - matches = re.match(r"\s*(?P\S+) \((?P\S+)\)", thread_line) - if not matches: - return None - return Thread(**matches.groupdict()) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/integration_test.rs b/tests/integration_test.rs index efaf7ddf..23fa155a 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -9,7 +9,7 @@ struct TestRunner { impl TestRunner { fn new(config: Config, filename: &str) -> TestRunner { - let child = std::process::Command::new("python").arg(filename).spawn().unwrap(); + let child = std::process::Command::new("python3").arg(filename).spawn().unwrap(); std::thread::sleep(std::time::Duration::from_millis(400)); let spy = PythonSpy::retry_new(child.id() as _, &config, 20).unwrap(); @@ -102,3 +102,61 @@ fn test_long_sleep() { #[cfg(any(target_os="macos", target_os="windows"))] assert!(!traces[0].active); } + +#[test] +fn test_recursive() { + #[cfg(target_os="macos")] + { + // We need root permissions here to run this on OSX + if unsafe { libc::geteuid() } != 0 { + return; + } + } + + // there used to be a problem where the top-level functions being returned + // weren't actually entry points: https://github.com/benfred/py-spy/issues/56 + // This was fixed by locking the process while we are profling it. Test that + // the fix works by generating some samples from a program that would exhibit + // this behaviour + let mut runner = TestRunner::new(Config::default(), "./tests/scripts/recursive.py"); + + for _ in 0..100 { + let traces = runner.spy.get_stack_traces().unwrap(); + assert_eq!(traces.len(), 1); + let trace = &traces[0]; + + assert!(trace.frames.len() <= 22); + + let top_level_frame = &trace.frames[trace.frames.len()-1]; + assert_eq!(top_level_frame.name, ""); + assert!((top_level_frame.line == 8) || (top_level_frame.line == 7)); + + std::thread::sleep(std::time::Duration::from_millis(5)); + } +} + +#[test] +fn test_unicode() { + #[cfg(target_os="macos")] + { + if unsafe { libc::geteuid() } != 0 { + return; + } + } + let mut runner = TestRunner::new(Config::default(), "./tests/scripts/unicode💩.py"); + + let traces = runner.spy.get_stack_traces().unwrap(); + assert_eq!(traces.len(), 1); + let trace = &traces[0]; + + assert_eq!(trace.frames[0].name, "sléép"); + assert_eq!(trace.frames[0].filename, "./tests/scripts/unicode💩.py"); + assert_eq!(trace.frames[0].line, 6); + + assert_eq!(trace.frames[1].name, ""); + assert_eq!(trace.frames[1].line, 9); + assert_eq!(trace.frames[0].filename, "./tests/scripts/unicode💩.py"); + + assert!(!traces[0].owns_gil); +} + diff --git a/tests/scripts/recursive.py b/tests/scripts/recursive.py new file mode 100755 index 00000000..b4148041 --- /dev/null +++ b/tests/scripts/recursive.py @@ -0,0 +1,8 @@ +def recurse(x): + if x == 0: + return + recurse(x-1) + + +while True: + recurse(20) diff --git "a/tests/scripts/unicode\360\237\222\251.py" "b/tests/scripts/unicode\360\237\222\251.py" new file mode 100755 index 00000000..caf7cf9e --- /dev/null +++ "b/tests/scripts/unicode\360\237\222\251.py" @@ -0,0 +1,9 @@ +#!/env/bin/python +# -*- coding: utf-8 -*- +import time + +def sléép(seconds): + time.sleep(seconds) + +if __name__ == "__main__": + sléép(1)