Skip to content

Instantly share code, notes, and snippets.

@dfuenzalida
Last active February 18, 2021 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dfuenzalida/664e1e5160c3f92046c260fd8500133f to your computer and use it in GitHub Desktop.
Save dfuenzalida/664e1e5160c3f92046c260fd8500133f to your computer and use it in GitHub Desktop.
Using jdb on bytecode compiled from clojure.core/compile

Software versions:

$ clj
Clojure 1.10.1

$ java -version
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment (build 11.0.10+9-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.10+9-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

Created a basic deps.edn file on the existing project:

deps.edn

{:paths ["src"]}

Created a classes directory to save the compiled files (otherwise the call to compile fails with Unexpected error (IOException) macroexpanding clojure.core/gen-class at (demo/core.clj:1:1).

$ mkdir classes

Started a clj REPL:

$ clj
Clojure 1.10.1
user=> (compile (symbol "demo.core"))
demo.core

Looked into the generated bytecode:

 javap -l classes/demo/core\$x2.class 
Compiled from "core.clj"
public final class demo.core$x2 extends clojure.lang.AFunction {
  public static final clojure.lang.Var const__0;

  public demo.core$x2();
    LineNumberTable:
      line 4: 0

  public static java.lang.Object invokeStatic(java.lang.Object);
    LineNumberTable:
      line 4: 0
      line 5: 6
      line 5: 12
      line 6: 24
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
         28       3     1     x   Ljava/lang/Object;
          0      31     0     n   Ljava/lang/Object;

  public java.lang.Object invoke(java.lang.Object);
    LineNumberTable:
      line 4: 3

  public static {};
    LineNumberTable:
      line 4: 0
}

The LineNumberTable entry contains a few more lines but I couldn't make it work as I expected. The rest of the process was about the same:

$ jdb -classpath classes:/home/denis/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar:/home/denis/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar:/home/denis/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar demo.core
Initializing jdb ...
> stop in demo.core$x2.invokeStatic
Deferring breakpoint demo.core$x2.invokeStatic.
It will be set after the class is loaded.
> run
run demo.core
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
> 
VM Started: Set deferred breakpoint demo.core$x2.invokeStatic

Breakpoint hit: "thread=main", demo.core$x2.invokeStatic(), line=4 bci=0

main[1] locals
Method arguments:
n = instance of java.lang.Long(id=2743)
Local variables:
main[1] print n
 n = "0"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment