diff --git a/cargo-klee/src/cli.rs b/cargo-klee/src/cli.rs
index e461c6c3068d8b89084c7bc56ef22b1424da8ade..b69ecede359a2940d1b7a381e0ddacfdb814d137 100644
--- a/cargo-klee/src/cli.rs
+++ b/cargo-klee/src/cli.rs
@@ -45,7 +45,7 @@ pub struct Cli {
 
     /// GDB Replay
     #[arg(long, short)]
-    pub replay: bool,
+    pub gdb: bool,
     // #[command(subcommand)]
     // binary: Option<Commands>,
 }
diff --git a/cargo-klee/src/main.rs b/cargo-klee/src/main.rs
index db6535fc8fac0bec4d02d2286581ad389c1767f3..8964e552e3dbf62ee338d91232d7e5c4c4d705f8 100644
--- a/cargo-klee/src/main.rs
+++ b/cargo-klee/src/main.rs
@@ -156,7 +156,7 @@ fn main() -> Result<(), Error> {
             // enable coloring of output
             .arg("--color")
             // ll file to analyse
-            .arg(ll);
+            .arg(ll.clone());
 
         println!("klee {:?}", klee);
 
@@ -174,11 +174,78 @@ fn main() -> Result<(), Error> {
         if !output.success() {
             return Err(anyhow!("`klee` failed, exiting `cargo-klee`"));
         }
+    }
 
-        let output = klee.stdout(Stdio::piped()).output()?;
-        let stderr = String::from_utf8(output.stderr)?;
+    // replay execution in `gdb`
+    if args.gdb {
+        // compile to object code for replay using `llc`
+        let mut llc = Command::new("llc");
+        llc.arg("-filetype=obj")
+            .arg("-relocation-model=pic")
+            .arg(ll.clone());
 
-        eprintln!("{}", stderr);
+        if args.verbose {
+            eprintln!("\n{:?}\n", llc);
+        }
+
+        let output = llc
+            .stdout(Stdio::piped())
+            .status()
+            .expect("failed to invoke `llc`, exiting `cargo-klee`");
+
+        if !output.success() {
+            return Err(anyhow!("`llc` failed, exiting `cargo-klee`"));
+        }
+
+        // compile to executable for replay using `clang`
+        let mut clang = Command::new("clang");
+
+        let obj_name = format!("{}.o", ll);
+        let replay_name = format!("{}.replay", ll);
+
+        clang
+            .arg(obj_name)
+            .arg("--rtlib=compiler-rt")
+            .arg("-lkleeRuntest")
+            .args(&["-o", &replay_name]);
+
+        if args.verbose {
+            eprintln!("\n{:?}\n", clang);
+        }
+
+        let output = llc
+            .stdout(Stdio::piped())
+            .status()
+            .expect("failed to invoke `clang`, exiting `cargo-klee`");
+
+        if !output.success() {
+            return Err(anyhow!("`clang` failed, exiting `cargo-klee`"));
+        }
+
+        let mut gdb = Command::new("gdb");
+        if let Ok(cwd) = env::var("GDB_CWD") {
+            // set gdb current dir to `GDB_CWD`
+            gdb.current_dir(cwd);
+        } else {
+            // set gdb current dir to the target directory
+            gdb.current_dir(out_dir);
+        };
+
+        // set replay name to be loaded by gdb
+        gdb.arg(replay_name);
+
+        if args.verbose {
+            eprintln!("\n{:?}\n", gdb);
+        }
+
+        let output = gdb
+            .stdout(Stdio::piped())
+            .status()
+            .expect("failed to invoke `gdb`, exiting `cargo-klee`");
+
+        if !output.success() {
+            return Err(anyhow!("`gdb` failed, exiting `cargo-klee`"));
+        }
     }
 
     println!("--- done ---");