Skip to content

ConsoleLine 忽略 fwrite 的回傳值:磁碟寫滿時警告會被截斷成「看起來完整」的一行 #150

Description

@kiki830621

Problem

ConsoleLine.write 丟棄 fwrite 的回傳值(成功寫入的 byte 數)。短寫(short write)時結果是一條被截斷但讀起來完整的診斷行——沒有終止符、下一行黏上來、且沒有任何跡象顯示發生過截斷。

ConsoleLine 的文件把取捨描述為「掉一條警告 好過 死一個 process」。實測到的第三種結果兩者都不是:一條倖存但內容已被改變的警告。對「輸出可信度」這條通道而言,靜默改變比靜默遺失更糟——遺失至少不會說謊。

Type

bug

Evidence

RLIMIT_FSIZE=40 的無緩衝 stream 上,逐字複製 emit 的迴圈對兩條警告執行:

  asked 49 bytes, wrote 40   <-- SHORT WRITE (ignored)
  asked 16 bytes, wrote 0    <-- SHORT WRITE (ignored)
  resulting stderr: "warning: first-warning-that-will-be-cut-"
  lines beginning 'warning:': 1 (expected 2)

可達性與當初促成 fputsfwrite 轉換的 NUL 情境相當:磁碟寫滿、quota 用盡、或 stderr 被導向受限的檔案系統。

已知的邊界(不要在這裡鑽)

SIGPIPE 可能在取得回傳值之前就終止 process——重試或忽略回傳值都處理不了那個情況。這個 issue 只針對回傳了短寫計數的路徑,不是「讓 ConsoleLine 對所有寫入失敗都健壯」。

可能的方向(未定案)

  • best-effort 策略:短寫就停止該行,但留下痕跡(例如截斷標記),讓截斷可見而非隱形。
  • 完整寫出:從回傳的 offset 續寫,直到完成或無進展(需要進展判斷以免無窮迴圈)。

前者較符合「診斷通道不該讓 process 死掉」的既有取捨,同時修掉「靜默說謊」這個真正的問題。

發現於 PR #141 round-3 verify(logic lens,L6)。相關:#136

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions