clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.11.57"}}}' \
- -M -m cljs.main -t nodejs ./org/foo/myscript.cljs
-diff --git a/docs/user_guide.adoc b/docs/user_guide.adoc index 598fc907..96ad7f95 100644 --- a/docs/user_guide.adoc +++ b/docs/user_guide.adoc @@ -1343,33 +1343,6 @@ From left to right : - Open the bookmarks window. - Quick jump. Use it for quickly jumping to the first recording of a function. Will autocomplete the first 25 matches. -== Debug cmd line programs (clj -X, clj -m, etc) - -If you run any Clojure programs from the command line, by using `clj -X ...`, `clj -m ...` etc, -you can use `flow-storm.api/cli-run` as a trampoline, to start a debugger, instrument everything you are interested in an then -run you original command. - -As an example, let's say you are compiling ClojureScript code like this : - -[,bash] ----- -clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.11.57"}}}' \ - -M -m cljs.main -t nodejs ./org/foo/myscript.cljs ----- - -you can then run and debug the execution of the same command like this : - -[,bash] ----- -clj -Sforce -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.11.57"} com.github.flow-storm/flow-storm-dbg {:mvn/version "RELEASE"} com.github.flow-storm/flow-storm-inst {:mvn/version "RELEASE"}}}' \ - -X flow-storm.api/cli-run :instrument-ns '#{"cljs."}' \ - :profile ':light' \ - :require-before '#{"cljs.repl.node"}' \ - :excluding-ns '#{"cljs.vendor.cognitect.transit"}' \ - :fn-symb 'cljs.main/-main' \ - :fn-args '["-t" "nodejs" "./org/foo/myscript.cljs"]'; ----- - == Programmable debugging _FlowStorm_ gives you full access to its internal indexes from the repl in Clojure and ClojureScript. @@ -1614,26 +1587,23 @@ If the value implements clojure.lang.IDeref (or cljs.core.IDeref in Cljs) a snap so no need to implement `flow-storm.runtime.values/snapshot-value` ==== -== Dealing with too many traces - -If you are tracing some code that ends up in a infinite loop the debugger will probably choke on -too many traces, making everything slow and where your only option is to restart it. +== Debugging infinite loop/recursion -For preventing this _FlowStorm_ provides a couple of tools : +If you are tracing some code that ends up in a infinite loop the debugger will choke on +too many traces, making everything slow and where your only option is probably to restart it. -*If you are using vanilla FlowStorm* there is `:thread-trace-limit`, you can use it like this : +For preventing this _FlowStorm_ provides fuse, called thread trace limit. [,clojure] ---- -#rtrace ^{:thread-trace-limit 200} ;; set our fuse at 200 -(loop [i 0] - (if (> i 100) - 42 ;; we will never reach here - (recur i))) +(require '[flow-storm.api :as fsa]) + +(fsa/set-thread-trace-limit 1000) ;; To set a limit of 1000 +(fsa/set-thread-trace-limit 0) ;; To disable it ---- -the infinite loop will be cut after 200 iterations by a thread-trace-limit exceeded exception, and you will have the traces on -the debugger to figure out what went wrong. +After the limit is set, if you run any code that generates more than a 1000 traces the code will stop at trace 1000 with +a thread-trace-limit exception, and you will have the recordings so far available. == Controlling instrumentation diff --git a/docs/user_guide.html b/docs/user_guide.html index 3a2b7695..ed530002 100644 --- a/docs/user_guide.html +++ b/docs/user_guide.html @@ -747,48 +747,47 @@
If you run any Clojure programs from the command line, by using clj -X …
, clj -m …
etc,
-you can use flow-storm.api/cli-run
as a trampoline, to start a debugger, instrument everything you are interested in an then
-run you original command.
As an example, let’s say you are compiling ClojureScript code like this :
-clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.11.57"}}}' \
- -M -m cljs.main -t nodejs ./org/foo/myscript.cljs
-you can then run and debug the execution of the same command like this :
-clj -Sforce -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.11.57"} com.github.flow-storm/flow-storm-dbg {:mvn/version "RELEASE"} com.github.flow-storm/flow-storm-inst {:mvn/version "RELEASE"}}}' \
- -X flow-storm.api/cli-run :instrument-ns '#{"cljs."}' \
- :profile ':light' \
- :require-before '#{"cljs.repl.node"}' \
- :excluding-ns '#{"cljs.vendor.cognitect.transit"}' \
- :fn-symb 'cljs.main/-main' \
- :fn-args '["-t" "nodejs" "./org/foo/myscript.cljs"]';
-FlowStorm gives you full access to its internal indexes from the repl in Clojure and ClojureScript. These allows you to explore your recordings using Clojure and write small programs to analyze @@ -3009,7 +2977,7 @@
Let’s say you want to explore recordings on thread 32. You can retrieve its timeline by calling ia/get-timeline
like this :
You can retrieve forms by form id with get-form
and then use get-sub-form-at-coord
and a coordinate.
If you have recorded a multi-thread timeline, you can retrieve it with total-order-timeline
like this :
There are other utitities in the api ns that could be useful, some of the most interesting ones :
FlowStorm will retain all values pointers when code executes so you can analyze them later. This works great with immutable values but when your code uses mutable values like this :
@@ -3340,33 +3308,29 @@If you are tracing some code that ends up in a infinite loop the debugger will probably choke on -too many traces, making everything slow and where your only option is to restart it.
-For preventing this FlowStorm provides a couple of tools :
+If you are tracing some code that ends up in a infinite loop the debugger will choke on +too many traces, making everything slow and where your only option is probably to restart it.
If you are using vanilla FlowStorm there is :thread-trace-limit
, you can use it like this :
For preventing this FlowStorm provides fuse, called thread trace limit.
#rtrace ^{:thread-trace-limit 200} ;; set our fuse at 200
-(loop [i 0]
- (if (> i 100)
- 42 ;; we will never reach here
- (recur i)))
+(require '[flow-storm.api :as fsa])
+
+(fsa/set-thread-trace-limit 1000) ;; To set a limit of 1000
+(fsa/set-thread-trace-limit 0) ;; To disable it
the infinite loop will be cut after 200 iterations by a thread-trace-limit exceeded exception, and you will have the traces on -the debugger to figure out what went wrong.
+After the limit is set, if you run any code that generates more than a 1000 traces the code will stop at trace 1000 with +a thread-trace-limit exception, and you will have the recordings so far available.
If you are using ClojureStorm or ClojureScriptStorm it is important to learn how to control what gets instrumented and how to uninstrument things.
@@ -3403,7 +3367,7 @@You can disable/enable instrumentation by evaluating the keys :noinst
and :inst
on your repl.
Disabling/enabling instrumentation will not reload your code, so if you need to re-evaluate the forms you are interested
@@ -3429,7 +3393,7 @@
You can add,remove and check your prefixes and also enable/disable instrumentation in ClojureScript with your Clojure repl (not the Cljs one) by calling :
@@ -3459,7 +3423,7 @@All functions that start the debugger ui (flow-storm.api/local-connect
, flow-storm.debugger.main/start-debugger
) accept a map
with the :styles
, :title
and :theme
keywords. If :styles
points to a css file it will be used to overwrite the default styles, in case you
@@ -3489,9 +3453,9 @@
Debugging ClojureScript react native application needs a combination of ClojureScript and remote debugging.
For those using WSL2 on Windows. You’ll need to set up an X-Server on Windows, make sure you drill a hole in the firewall for the port, and then specify the display for the WSL process.
Checkout Cider Storm an Emacs Cider front-end with support for Clojure and ClojureScript.
By default functions like flow-storm.api/instrument-namespaces-clj
will not print warnings on the console. You can log extra information
by providing :verbose? true
to the options map.
#rtrace form
just expands to (flow-storm.api/runi {} form)
.
FlowStorm UI requires JDK >= 17. If you can’t upgrade your JDK you can still use it by downgrading JavaFx.
For people interested in enhancing, troubleshooting, fixing or just learning about FlowStorm internals take a look at here :