Skip to content

Commit 4ae6e22

Browse files
authored
Improve debugger stability (#457)
* remove legacy io_request handlers we don't support OTP < R15B * rescue MatchError in :int calls Fixes #455 * make output device better conform to erlang I/O protocol see https://erlang.org/doc/apps/stdlib/io_protocol.html for details * return WireProtocol.send error to the caller no need to IO.warn if write fails * we are redirection stderr to stdout, use stdout as underlying device * inspect error * monitor debugged processes add test for mix task exit Fixes #454 * avoid debugger crashes when handling requests for no longer existing thread, frame and variable ids Fixes #452 * add test * forbid changes of underlying device opts * refactor and add tests coverage to invalid requests * Map.pop! is available since elixir 1.10 * run formatter
1 parent e8c381b commit 4ae6e22

File tree

10 files changed

+992
-188
lines changed

10 files changed

+992
-188
lines changed

apps/elixir_ls_debugger/lib/debugger/cli.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule ElixirLS.Debugger.CLI do
66
WireProtocol.intercept_output(&Output.print/1, &Output.print_err/1)
77
Launch.start_mix()
88
{:ok, _} = Application.ensure_all_started(:elixir_ls_debugger, :permanent)
9+
910
IO.puts("Started ElixirLS debugger v#{Launch.debugger_version()}")
1011
Launch.print_versions()
1112
Launch.limit_num_schedulers()

apps/elixir_ls_debugger/lib/debugger/output.ex

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule ElixirLS.Debugger.Output do
77
are sent with sequence numbers that are unique and sequential, and includes client functions for
88
sending these messages.
99
"""
10-
import ElixirLS.Utils.WireProtocol, only: [send: 1]
10+
alias ElixirLS.Utils.WireProtocol
1111
use GenServer
1212
use ElixirLS.Debugger.Protocol
1313

@@ -29,12 +29,12 @@ defmodule ElixirLS.Debugger.Output do
2929
GenServer.call(server, {:send_event, event, body})
3030
end
3131

32-
def print(server \\ __MODULE__, str) do
33-
send_event(server, "output", %{"category" => "stdout", "output" => to_string(str)})
32+
def print(server \\ __MODULE__, str) when is_binary(str) do
33+
send_event(server, "output", %{"category" => "stdout", "output" => str})
3434
end
3535

36-
def print_err(server \\ __MODULE__, str) do
37-
send_event(server, "output", %{"category" => "stderr", "output" => to_string(str)})
36+
def print_err(server \\ __MODULE__, str) when is_binary(str) do
37+
send_event(server, "output", %{"category" => "stderr", "output" => str})
3838
end
3939

4040
## Server callbacks
@@ -46,27 +46,28 @@ defmodule ElixirLS.Debugger.Output do
4646

4747
@impl GenServer
4848
def handle_call({:send_response, request_packet, body}, _from, seq) do
49-
send(response(seq, request_packet["seq"], request_packet["command"], body))
50-
{:reply, :ok, seq + 1}
49+
res = WireProtocol.send(response(seq, request_packet["seq"], request_packet["command"], body))
50+
{:reply, res, seq + 1}
5151
end
5252

5353
def handle_call({:send_error_response, request_packet, message, format, variables}, _from, seq) do
54-
send(
55-
error_response(
56-
seq,
57-
request_packet["seq"],
58-
request_packet["command"],
59-
message,
60-
format,
61-
variables
54+
res =
55+
WireProtocol.send(
56+
error_response(
57+
seq,
58+
request_packet["seq"],
59+
request_packet["command"],
60+
message,
61+
format,
62+
variables
63+
)
6264
)
63-
)
6465

65-
{:reply, :ok, seq + 1}
66+
{:reply, res, seq + 1}
6667
end
6768

6869
def handle_call({:send_event, event, body}, _from, seq) do
69-
send(event(seq, event, body))
70-
{:reply, :ok, seq + 1}
70+
res = WireProtocol.send(event(seq, event, body))
71+
{:reply, res, seq + 1}
7172
end
7273
end

0 commit comments

Comments
 (0)