From 2e0cd0c53478c65ab3f1b10f97b16e3dbfb7d51d Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Fri, 1 Nov 2024 18:47:53 -0700 Subject: [PATCH 1/3] Use rust-lldb for macos or if rust-gdb not available --- main/src/main.rs | 61 +++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/main/src/main.rs b/main/src/main.rs index 82e781a..99d8812 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -7,8 +7,7 @@ use constants::DEFAULT_ENDPOINT; use ethers::abi::Bytes; use ethers::types::{H160, U256}; use eyre::{bail, eyre, Context, Result}; -use std::path::PathBuf; -use std::{fmt, path::Path}; +use std::{fmt, path::{Path, PathBuf}}; use tokio::runtime::Builder; use trace::Trace; use util::{color::Color, sys}; @@ -487,10 +486,7 @@ fn main() -> Result<()> { // supported. These extensions are now incorporated as part of the `cargo-stylus` command itself and // will be the preferred method of running them. fn is_deprecated_extension(subcommand: &str) -> bool { - match subcommand { - "cargo-stylus-check" | "cargo-stylus-cgen" | "cargo-stylus-replay" => true, - _ => false, - } + matches!(subcommand, "cargo-stylus-check" | "cargo-stylus-cgen" | "cargo-stylus-replay") } async fn main_impl(args: Opts) -> Result<()> { @@ -612,35 +608,52 @@ async fn simulate(args: SimulateArgs) -> Result<()> { async fn replay(args: ReplayArgs) -> Result<()> { if !args.child { - let rust_gdb = sys::command_exists("rust-gdb"); - if !rust_gdb { - println!( - "{} not installed, falling back to {}", - "rust-gdb".red(), - "gdb".red() - ); - } - - let mut cmd = match rust_gdb { - true => sys::new_command("rust-gdb"), - false => sys::new_command("gdb"), + let macos = cfg!(target_os = "macos"); + let gdb_args = [ + "--quiet", + "-ex=set breakpoint pending on", + "-ex=b user_entrypoint", + "-ex=r", + "--args", + ].as_slice(); + let lldb_args = [ + "--source-quietly", + "-o", + "b user_entrypoint", + "-o", + "r", + "--", + ].as_slice(); + let (cmd_name, args) = if sys::command_exists("rust-gdb") && !macos { + ("rust-gdb", &gdb_args) + } else if sys::command_exists("rust-lldb") { + ("rust-lldb", &lldb_args) + } else { + println!("rust specific debugger not installed, falling back to generic debugger"); + if sys::command_exists("gdb") && !macos { + ("gdb", &gdb_args) + } else if sys::command_exists("lldb") { + ("lldb", &lldb_args) + } else { + bail!("no debugger found") + } }; - cmd.arg("--quiet"); - cmd.arg("-ex=set breakpoint pending on"); - cmd.arg("-ex=b user_entrypoint"); - cmd.arg("-ex=r"); - cmd.arg("--args"); + let mut cmd = sys::new_command(cmd_name); + for arg in args.iter() { + cmd.arg(arg); + } for arg in std::env::args() { cmd.arg(arg); } cmd.arg("--child"); + #[cfg(unix)] let err = cmd.exec(); #[cfg(windows)] let err = cmd.status(); - bail!("failed to exec gdb {:?}", err); + bail!("failed to exec {cmd_name} {:?}", err); } let provider = sys::new_provider(&args.trace.endpoint)?; From 42be9a2ddd84549869768df2e12094cfff519ccb Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Sun, 3 Nov 2024 19:27:06 -0700 Subject: [PATCH 2/3] cargo fmt fixes --- main/src/main.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/main/src/main.rs b/main/src/main.rs index 99d8812..578e546 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -7,7 +7,10 @@ use constants::DEFAULT_ENDPOINT; use ethers::abi::Bytes; use ethers::types::{H160, U256}; use eyre::{bail, eyre, Context, Result}; -use std::{fmt, path::{Path, PathBuf}}; +use std::{ + fmt, + path::{Path, PathBuf}, +}; use tokio::runtime::Builder; use trace::Trace; use util::{color::Color, sys}; @@ -486,7 +489,10 @@ fn main() -> Result<()> { // supported. These extensions are now incorporated as part of the `cargo-stylus` command itself and // will be the preferred method of running them. fn is_deprecated_extension(subcommand: &str) -> bool { - matches!(subcommand, "cargo-stylus-check" | "cargo-stylus-cgen" | "cargo-stylus-replay") + matches!( + subcommand, + "cargo-stylus-check" | "cargo-stylus-cgen" | "cargo-stylus-replay" + ) } async fn main_impl(args: Opts) -> Result<()> { @@ -615,7 +621,8 @@ async fn replay(args: ReplayArgs) -> Result<()> { "-ex=b user_entrypoint", "-ex=r", "--args", - ].as_slice(); + ] + .as_slice(); let lldb_args = [ "--source-quietly", "-o", @@ -623,7 +630,8 @@ async fn replay(args: ReplayArgs) -> Result<()> { "-o", "r", "--", - ].as_slice(); + ] + .as_slice(); let (cmd_name, args) = if sys::command_exists("rust-gdb") && !macos { ("rust-gdb", &gdb_args) } else if sys::command_exists("rust-lldb") { From 6bcb17c5eb6b8bdd374966fbbd647622e5d7f834 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Mon, 4 Nov 2024 11:57:58 -0700 Subject: [PATCH 3/3] Use `.dylib` for macos --- main/src/main.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/main/src/main.rs b/main/src/main.rs index 578e546..59c4b9b 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -613,8 +613,8 @@ async fn simulate(args: SimulateArgs) -> Result<()> { } async fn replay(args: ReplayArgs) -> Result<()> { + let macos = cfg!(target_os = "macos"); if !args.child { - let macos = cfg!(target_os = "macos"); let gdb_args = [ "--quiet", "-ex=set breakpoint pending on", @@ -667,8 +667,9 @@ async fn replay(args: ReplayArgs) -> Result<()> { let provider = sys::new_provider(&args.trace.endpoint)?; let trace = Trace::new(provider, args.trace.tx, args.trace.use_native_tracer).await?; - build_so(&args.trace.project)?; - let so = find_so(&args.trace.project)?; + build_shared_library(&args.trace.project)?; + let library_extension = if macos { ".dylib" } else { ".so" }; + let shared_library = find_shared_library(&args.trace.project, library_extension)?; // TODO: don't assume the contract is top-level let args_len = trace.tx.input.len(); @@ -677,7 +678,7 @@ async fn replay(args: ReplayArgs) -> Result<()> { *hostio::FRAME.lock() = Some(trace.reader()); type Entrypoint = unsafe extern "C" fn(usize) -> usize; - let lib = libloading::Library::new(so)?; + let lib = libloading::Library::new(shared_library)?; let main: libloading::Symbol = lib.get(b"user_entrypoint")?; match main(args_len) { @@ -689,7 +690,7 @@ async fn replay(args: ReplayArgs) -> Result<()> { Ok(()) } -pub fn build_so(path: &Path) -> Result<()> { +pub fn build_shared_library(path: &Path) -> Result<()> { let mut cargo = sys::new_command("cargo"); cargo @@ -703,7 +704,7 @@ pub fn build_so(path: &Path) -> Result<()> { Ok(()) } -pub fn find_so(project: &Path) -> Result { +pub fn find_shared_library(project: &Path, extension: &str) -> Result { let triple = rustc_host::from_cli()?; let so_dir = project.join(format!("target/{triple}/debug/")); let so_dir = std::fs::read_dir(&so_dir) @@ -719,7 +720,7 @@ pub fn find_so(project: &Path) -> Result { }; let ext = ext.to_string_lossy(); - if ext.contains(".so") { + if ext.contains(extension) { if let Some(other) = file { let other = other.file_name().unwrap().to_string_lossy(); bail!("more than one .so found: {ext} and {other}",);