lwIP sockets: a failed listen or connect leaves the socket lock held, a later close hangs forever
メンテナーはふだん 3 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 84/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- c, erlang
- 領域
- embedded-iot
調査の方向性
src/libAtomVM/otp_socket.c から始め、nif_socket_listen と nif_socket_connect の lwIP 分岐を読みます。#2345 が tcp_close のエラーパスでソケットロックをどう扱うかを確認し、SMP RP2 ビルドで listen または connect の失敗を再現します。各エラーパスで読み取りロックが解放され、失敗後に socket:close が戻ることを確認できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Affected: release-0.7 at ca1583068, lwIP socket backend (RP2 port), SMP builds
(the default on RP2). Not changed by #2345.
What happens
nif_socket_listen and nif_socket_connect take the socket read lock, then
return on an lwIP error without releasing it:
nif_socket_listen:if (new_pcb == NULL) { return make_lwip_err_tuple(err, ctx); }nif_socket_connect(lwIP branch):if (err != ERR_OK) { ... return {error, closed} / RAISE_ERROR(...) }
The read lock is never released. Every later operation that takes the write lock
on that socket blocks forever and pins a scheduler thread: socket:close/1,
socket:recv/1,2,3, socket:accept/1,2, socket:send/2 (through the select
NIFs) and the monitor callback socket_down.
How to reproduce (Pico W)
Connect, with the network down or no route to the address (tcp_connect fails
with ERR_RTE):
{ok, S} = socket:open(inet, stream, tcp),
{error, closed} = socket:connect(S, #{family => inet, addr => {192, 168, 0, 1}, port => 80}),
ok = socket:close(S). % never returns
Listen on a socket that is already connected (tcp_listen fails with ERR_CLSD):
{error, _} = socket:listen(ConnectedSocket),
ok = socket:close(ConnectedSocket). % never returns
Where
src/libAtomVM/otp_socket.c, nif_socket_listen and nif_socket_connect,
#elif OTP_SOCKET_LWIP branches.
Suggested fix
SMP_RWLOCK_UNLOCK(rsrc_obj->socket_lock) before returning on both error
paths, as #2345 did for the failing tcp_close in nif_socket_close.
- 主要言語
- Erlang
- スター
- 2.3k
- フォーク
- 171
- 平均マージ
- 4日 11時間
- マージ済み PR(30日)
- 20
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
atomvm/AtomVM のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
メンテナーはふだん 3 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
config ⚙
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
micropython/micropython#19942 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100