|
14 | 14 | (def ^:private response-pattern-202 #"^202 Paused\s+(.+)\s+([0-9]+)\s*$") |
15 | 15 | (def ^:private response-pattern-203 #"^203 Paused\s+(.+)\s+([0-9]+)\s+([0-9]+)\s*$") |
16 | 16 | (def ^:private response-pattern-204 #"^204 Output (\w+) (\d+)$") |
17 | | -(def ^:private response-pattern-401 #"^401 Error in Execution (\d+)\s*$") |
| 17 | +(def ^:private response-pattern-401 #"^401 Error in (\w+) (\d+)\s*$") |
18 | 18 |
|
19 | 19 | (defn- send-line! [server ^String line] |
20 | 20 | (let [^PrintWriter writer (get-in server [:client :writer])] |
|
30 | 30 | (log/debug "Debuggee -> Debug Server:" message) |
31 | 31 | (string/trim message)))) |
32 | 32 |
|
33 | | -(defn- send-command! [server command] |
| 33 | +(defn- read-response-with-length! [server len] |
| 34 | + (let [^BufferedReader reader (get-in server [:client :reader]) |
| 35 | + len (Integer/parseInt len) |
| 36 | + buffer (char-array len)] |
| 37 | + (.read reader buffer 0 len) |
| 38 | + (let [res (String/new buffer)] |
| 39 | + (log/debug (format "Debuggee -> Debug Server (%s): %s" len res)) |
| 40 | + res))) |
| 41 | + |
| 42 | +(defn- send-blocking-command! [server command] |
34 | 43 | (let [^Socket socket (get-in server [:client :socket]) |
35 | 44 | command (string/upper-case command)] |
36 | 45 | (send-line! server command) |
|
61 | 70 | (do (log/info "Paused at file:" file "line:" line "( watch expression:" watch-index ")") |
62 | 71 | nil) |
63 | 72 | (recur)) |
64 | | - "204" (if-let [[_ text size] (re-find response-pattern-204 breakpoint)] |
65 | | - (let [size (parse-long size) |
66 | | - message (if (pos? size) (read-response! server) "")] |
| 73 | + "204" (if-let [[_ text len] (re-find response-pattern-204 breakpoint)] |
| 74 | + (let [size (parse-long len) |
| 75 | + message (if (pos? size) (read-response-with-length! server size) "")] |
67 | 76 | (log/debug "OUT1:" text) |
68 | 77 | (log/debug "OUT2:" message) |
69 | 78 | (recur)) |
70 | 79 | (recur)) |
71 | | - "401" (if-let [[_ _size] (re-find response-pattern-401 breakpoint)] |
72 | | - (let [message (read-response! server)] |
73 | | - (log/error "Error in remote application:" message) |
| 80 | + "401" (if-let [[_ error-type size] (re-find response-pattern-401 breakpoint)] |
| 81 | + (let [message (read-response-with-length! server size)] |
| 82 | + (log/error "Error in remote application:" error-type message) |
74 | 83 | nil) |
75 | 84 | (recur)) |
76 | 85 | (do (log/error "Unknown Error:" breakpoint) |
|
88 | 97 | (lua/extract-table stack-code) |
89 | 98 | nil)) |
90 | 99 |
|
| 100 | +(defn- convert-to-safe-whitespace [s] |
| 101 | + (string/replace s #"\r?\n" "\012")) |
| 102 | + |
| 103 | +(defn- send-eval-command! [server expression] |
| 104 | + (try |
| 105 | + (send-line! |
| 106 | + server |
| 107 | + (format |
| 108 | + (if (lua/expression? expression) |
| 109 | + "EXEC return %s" |
| 110 | + "EXEC %s") |
| 111 | + (convert-to-safe-whitespace expression))) |
| 112 | + (let [res (read-response! server) |
| 113 | + [_ status] (re-find #"^(\d+)" res)] |
| 114 | + (case status |
| 115 | + "200" (when-let [[_ len] (re-find response-pattern-200 res)] |
| 116 | + (let [res (read-response-with-length! server len)] |
| 117 | + (first (lua/extract-table res)))) |
| 118 | + |
| 119 | + "204" (when-let [[_ text len] (re-find response-pattern-204 res)] |
| 120 | + (let [size (parse-long len) |
| 121 | + message (if (pos? size) (read-response-with-length! server size) "")] |
| 122 | + (log/debug "OUT1:" text) |
| 123 | + (log/debug "OUT2:" message) |
| 124 | + nil)) |
| 125 | + |
| 126 | + "401" (when-let [[_ error-type len] (re-find response-pattern-401 res)] |
| 127 | + (let [res (read-response-with-length! server len)] |
| 128 | + (log/error (format "Eval Error in %s: %s" error-type res)) |
| 129 | + res)) |
| 130 | + |
| 131 | + (do (log/error "Unknown Error:" res) |
| 132 | + nil))) |
| 133 | + (catch Throwable t |
| 134 | + (log/error "Eval: Something went wrong:" (pr-str (parse-exception t)))))) |
| 135 | + |
91 | 136 | (defn- is-connected? [^Socket socket] |
92 | 137 | (and (not (.isClosed socket)) |
93 | 138 | (.isConnected socket) |
|
111 | 156 | :to-debug-server to-debug-server}}] |
112 | 157 |
|
113 | 158 | ; send step command |
114 | | - (send-command! server-handle "step") |
| 159 | + (send-blocking-command! server-handle "step") |
115 | 160 | (>!! to-adapter {:cmd :setup-done}) |
116 | 161 |
|
117 | 162 | (go-loop [] |
118 | 163 | (when-let [command (<!! to-debug-server)] |
119 | 164 | (log/debug "Handler -> Debug Server:" command) |
120 | 165 | (case (:cmd command) |
121 | | - :run (go (send-command! server-handle "run")) |
| 166 | + :run (go (send-blocking-command! server-handle "run")) |
122 | 167 |
|
123 | 168 | :set-breakpoints (do |
124 | 169 | ; this command only gets called before executing a command so we |
|
129 | 174 | {:keys [line]} breakpoints] |
130 | 175 | (send-command-setb! server-handle filename line))) |
131 | 176 |
|
132 | | - :step-in (go (send-command! server-handle "step")) |
| 177 | + :step-in (go (send-blocking-command! server-handle "step")) |
133 | 178 |
|
134 | | - :step-out (go (send-command! server-handle "out")) |
| 179 | + :step-out (go (send-blocking-command! server-handle "out")) |
135 | 180 |
|
136 | | - :over (go (send-command! server-handle "over")) |
| 181 | + :over (go (send-blocking-command! server-handle "over")) |
137 | 182 |
|
138 | 183 | :stacktrace (let [stack (send-command-stack! server-handle)] |
139 | 184 | (>!! to-adapter {:cmd :stacktrace :stack stack :seq (:seq command)})) |
140 | 185 |
|
| 186 | + :eval (let [result (send-eval-command! server-handle (:expression command))] |
| 187 | + (>!! to-adapter {:cmd :eval :result result :seq (:seq command)})) |
| 188 | + |
141 | 189 | :exit (do |
142 | | - (send-command! server-handle "exit") |
| 190 | + (send-blocking-command! server-handle "exit") |
143 | 191 | (.close client) |
144 | 192 | (System/exit 0)) |
145 | 193 |
|
|
0 commit comments