{"id":15405081,"url":"https://github.com/razum2um/clj-debugger","last_synced_at":"2025-04-04T16:15:10.352Z","repository":{"id":22711804,"uuid":"26056017","full_name":"razum2um/clj-debugger","owner":"razum2um","description":"The missing tool","archived":false,"fork":false,"pushed_at":"2018-06-07T13:46:10.000Z","size":70,"stargazers_count":268,"open_issues_count":2,"forks_count":11,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-28T15:08:20.803Z","etag":null,"topics":["clojure","debugger"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/razum2um.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-01T16:30:39.000Z","updated_at":"2024-12-12T08:22:27.000Z","dependencies_parsed_at":"2022-07-27T03:17:25.227Z","dependency_job_id":null,"html_url":"https://github.com/razum2um/clj-debugger","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razum2um%2Fclj-debugger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razum2um%2Fclj-debugger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razum2um%2Fclj-debugger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razum2um%2Fclj-debugger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/razum2um","download_url":"https://codeload.github.com/razum2um/clj-debugger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247208151,"owners_count":20901570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","debugger"],"created_at":"2024-10-01T16:14:57.929Z","updated_at":"2025-04-04T16:15:10.330Z","avatar_url":"https://github.com/razum2um.png","language":"Clojure","funding_links":[],"categories":["Debugging"],"sub_categories":[],"readme":"# Debugger\n\n[![Build Status](https://travis-ci.org/razum2um/clj-debugger.svg?branch=master)](https://travis-ci.org/razum2um/clj-debugger)\n\n[![Clojars Project](http://clojars.org/debugger/latest-version.svg)](http://clojars.org/debugger)\n\nThe missing tools in the Clojure ecosystem.\n\n- [break/break-catch: interactive breakpoint](#usage)\n- [dbg: debug intermediate expressions](#debug-intermediate-expressions)\n- [dbg-defn/dbg-fn: debug incoming arguments](#debug-incoming-arguments)\n\n## Usage\n\n```clj\n(use 'debugger.core)\n\n(break (some-fn))\n\n(break-catch (some-raising-fn))\n```\n\n### Breakpoints\n\n```\nuser=\u003e (dotimes [n 5] (debugger.core-test/foo n))\n\nBreak from: /Users/razum2um/Code/debugger/src/debugger/core_test.clj:12 (type \"(help)\" for help)\n\n   17:         e (fn [] nil)\n   18:         x \"world\"\n   19:         y '(8 9)\n   20:         z (Object.)\n=\u003e 21:         ret (break (inc 42))]\n   22:     (println \"Exit foo with\" ret)))\n```\n\n### Interactive help\n\n```\ndebugger.core-test/qux:31=\u003e (h)\n\n (h)    (help)          prints this help\n        (wtf)           prints short code of breakpointed function\n        (wtf??)         prints full code of breakpointed function\n (l)    (locals)        prints locals\n (c)    (continue)      continues execution, preserves the result and will break here again\n        (skip 3)        skips next 3 breakpoints in this place\n (q)    (quit)          or type Ctrl-D to exit break-repl, pass last result further, will never break here anymore\n\n                        use (debugger.core/reset-skips!) if breaks are skipped\n                        you can also access locals directly and build sexp with them\n                        any last execution result (but `nil`) before exit will be passed further\n                        if last result is `nil` execution will continue normally\n\nnil\n```\n\n### Locals access\n\n```\ndebugger.core-test/foo:21=\u003e (l)\n{x \"world\",\n a [1 2],\n y (8 9),\n args nil,\n e #\u003ccore_test$foo$e__4735 debugger.core_test$foo$e__4735@6735cbba\u003e,\n z #\u003cObject java.lang.Object@2094643d\u003e,\n h {:k \"v\"},\n b #{4 3},\n d nil}\nnil\ndebugger.core-test/foo:21=\u003e z\n#\u003cObject java.lang.Object@3dc76ae9\u003e\n```\n\n### Return value control\n\nUse any non-nil value to fake inner result:\n\n```\nuser=\u003e (debugger.core-test/foo)\n\nBreak from: /Users/razum2um/Code/debugger/src/debugger/core_test.clj:12 (type \"(help)\" for help)\n\n   17:         e (fn [] nil)\n   18:         x \"world\"\n   19:         y '(8 9)\n   20:         z (Object.)\n=\u003e 21:         ret (break (inc 42))]\n   22:     (println \"Exit foo with\" ret)))\n\ndebugger.core-test/foo:21=\u003e 1                     ;; inner (inc 42) won't be called\n1\ndebugger.core-test/foo:21=\u003e Exit foo with 1       ;; used result from REPL\nnil\n```\n\n### Code expection\n\n```\ndebugger.core-test/foo:21=\u003e (whereami)\n\n   12: (defn foo [\u0026 args]\n   13:   (let [a [1 2]\n   14:         b #{3 4}\n   15:         h {:k \"v\"}\n   16:         d nil\n   17:         e (fn [] nil)\n   18:         x \"world\"\n   19:         y '(8 9)\n   20:         z (Object.)\n=\u003e 21:         ret (break (inc 42))]\n   22:     (println \"Exit foo with\" ret)))\n\nnil\n```\n\n### Stack expection\n\n```\ndebugger.core-test/foo:21=\u003e (wtf??)\n\n  [0]                      core_test.clj:21     debugger.core-test/foo\n  [1]                        RestFn.java:408    clojure.lang.RestFn\n  [2]   form-init1204084863726891616.clj:1      user/eval3682\n  [3]                      Compiler.java:6703   clojure.lang.Compiler\n  [4]                      Compiler.java:6666   clojure.lang.Compiler\n  [5]                           core.clj:2927   clojure.core/eval\n  [6]                           main.clj:239    clojure.main/repl\n  [7]                           main.clj:239    clojure.main/repl\n  [8]                           main.clj:257    clojure.main/repl\n  [9]                           main.clj:257    clojure.main/repl\n [10]                        RestFn.java:1523   clojure.lang.RestFn\n [11]             interruptible_eval.clj:67     clojure.tools.nrepl.middleware.interruptible-eval/evaluate\n [12]                           AFn.java:152    clojure.lang.AFn\n [13]                           AFn.java:144    clojure.lang.AFn\n [14]                           core.clj:624    clojure.core/apply\n [15]                           core.clj:1862   clojure.core/with-bindings*\n [16]                        RestFn.java:425    clojure.lang.RestFn\n [17]             interruptible_eval.clj:51     clojure.tools.nrepl.middleware.interruptible-eval/evaluate\n [18]             interruptible_eval.clj:183    clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval\n [19]             interruptible_eval.clj:152    clojure.tools.nrepl.middleware.interruptible-eval/run-next\n [20]                           AFn.java:22     clojure.lang.AFn\n [21]            ThreadPoolExecutor.java:1142   java.util.concurrent.ThreadPoolExecutor\n [22]            ThreadPoolExecutor.java:617    java.util.concurrent.ThreadPoolExecutor/Worker\n [23]                        Thread.java:745    java.lang.Thread\n\nnil\n\n```\n\n### Break on next `(break)` or skip it\n\n```\ndebugger.core-test/foo:21=\u003e (c)\n43\nExit foo with #\u003cObject java.lang.Object@3dc76ae9\u003e\n\nBreak from: /Users/razum2um/Code/debugger/src/debugger/core_test.clj:12 (type \"(help)\" for help)\n\n   17:         e (fn [] nil)\n   18:         x \"world\"\n   19:         y '(8 9)\n   20:         z (Object.)\n=\u003e 21:         ret (break (inc 42))]\n   22:     (println \"Exit foo with\" ret)))\n\ndebugger.core-test/foo:21=\u003e (skip 3)\nnil\nExit foo with 43\nExit foo with 43\nExit foo with 43\n\nBreak from: /Users/razum2um/Code/debugger/src/debugger/core_test.clj:12 (type \"(help)\" for help)\n\n   17:         e (fn [] nil)\n   18:         x \"world\"\n   19:         y '(8 9)\n   20:         z (Object.)\n=\u003e 21:         ret (break (inc 42))]\n   22:     (println \"Exit foo with\" ret)))\n\ndebugger.core-test/foo:21=\u003e (c)\n43\nExit foo with 43\nnil\n```\n\n### Breakpoints in threads\n```\nuser\u003e (debugger.core-test/in-thread)\nnil\nRegistered breakpoint: debugger.core_test$foo$breakpoint__20396__auto____20431@4c18a68e. \nType (breakpoints) to see a list of registered breakpoint, and (connect) to connect to one.\nuser\u003e (breakpoints)\nBreakpoints:\n0) debugger.core_test$foo$breakpoint__20396__auto____20431@4c18a68e\nnil\nuser\u003e (connect)\n\nBreak from: /Users/maxim/tmp/clj-debugger/src/debugger/core_test.clj:8 (type \"(help)\" for help)\n\n   13:         e (fn [] nil)\n   14:         x \"world\"\n   15:         y '(8 9)\n   16:         z (Object.)\n=\u003e 17:         ret (break (inc 42))]\n   18:     (println \"Exit foo with\" ret))) \n\ndebugger.core-test/foo:17=\u003e a\n[1 2]\ndebugger.core-test/foo:17=\u003e (q)\nQuitting debugger...\nnil\nnilExit foo with \n[1 2]\nuser\u003e \n```\n\n### Configuration\n\nThe following dynamic vars are configurable in `debugger.config`\n\n| Var | Default Value | Use |\n| ---| --- | --- |\n| `*break-outside-repl*` | `true` | Break in non-repl threads, since 0.2.0. Default value was  `false` in 0.1.x. |\n| `*code-context-lines*` | 5 | Number of lines to include when showing source. |\n| `*locals-print-length*` | 10 | Print-length for locals inside the debugger.   |\n| `*skip-repl-if-last-quit-ago*` |2 | Number of seconds to wait after a debugger is quit before starting another one. |\n\n### TODO\n\n- `(step)`, `(up)`, `(down)` stack manipulation\n\n## Debug intermediate expressions\n\n```clojure\nuser=\u003e (-\u003e 2 (+ 3) (* 4) dbg (/ 5))\n(* (+ 2 3) 4) -\u003e 20\n4\n```\n\n## Debug incoming arguments\n\n```clojure\nuser=\u003e (dbg-defn f1 [arg1 arg2] (+ arg1 arg2))\n#'user/f1\n\nuser=\u003e (f1 2 3)\n{arg1 2, arg2 3}\n5\n```\n\n## Acknowledgements\n\n- [@richhickey](http://github.com/richhichey) for `clojure.main/repl`\n- [@GeorgeJahad](http://github.com/GeorgeJahad) for the lesson [how to preserve locals](https://github.com/GeorgeJahad/debug-repl/blob/master/src/alex_and_georges/debug_repl.clj#L68)\n- [@mveytsman](https://github.com/mveytsman) for breakpoints in threads\n\n## YourKit\n\n\u003cimg src=\"http://www.yourkit.com/images/yklogo.png\"\u003e\u003c/img\u003e\n\nYourKit has given an open source license for their profiler, greatly simplifying the profiling of ClojureScript performance.\n\nYourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of \u003ca href=\"http://www.yourkit.com/java/profiler/index.jsp\"\u003eYourKit Java Profiler\u003c/a\u003e\nand \u003ca href=\"http://www.yourkit.com/.net/profiler/index.jsp\"\u003eYourKit .NET Profiler\u003c/a\u003e,\ninnovative and intelligent tools for profiling Java and .NET applications.\n\n## License\n\nCopyright © 2014-2018 Vlad Bokov\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frazum2um%2Fclj-debugger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frazum2um%2Fclj-debugger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frazum2um%2Fclj-debugger/lists"}